Core/Achievements: Fixed realm first kill achievement restrictions - now only the first group will be able to complete it

Closes #2957
This commit is contained in:
Shauren
2014-09-20 19:07:39 +02:00
parent b5cd540758
commit d87c23cdaf
3 changed files with 30 additions and 11 deletions

View File

@@ -1620,7 +1620,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 (sAchievementMgr->IsRealmCompleted(achievement))
if (sAchievementMgr->IsRealmCompleted(achievement, GetPlayer()->GetInstanceId()))
return false;
}
@@ -2027,10 +2027,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
ca.date = time(NULL);
ca.changed = true;
// 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))
sAchievementMgr->SetRealmCompleted(achievement);
sAchievementMgr->SetRealmCompleted(achievement, GetPlayer()->GetInstanceId());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points);
@@ -2405,7 +2402,7 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
continue;
}
else if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
m_allCompletedAchievements.insert(achievementId);
m_allCompletedAchievements[achievementId] = uint32(0xFFFFFFFF);
}
while (result->NextRow());
@@ -2582,3 +2579,10 @@ AchievementCriteriaEntry const* AchievementGlobalMgr::GetAchievementCriteria(uin
{
return sAchievementCriteriaStore.LookupEntry(criteriaId);
}
void AchievementGlobalMgr::OnInstanceDestroyed(uint32 instanceId)
{
for (auto& realmCompletion : m_allCompletedAchievements)
if (realmCompletion.second == instanceId)
realmCompletion.second = uint32(0xFFFFFFFF);
}

View File

@@ -355,16 +355,29 @@ class AchievementGlobalMgr
return iter != m_criteriaDataMap.end() ? &iter->second : NULL;
}
bool IsRealmCompleted(AchievementEntry const* achievement) const
bool IsRealmCompleted(AchievementEntry const* achievement, uint32 instanceId) const
{
return m_allCompletedAchievements.find(achievement->ID) != m_allCompletedAchievements.end();
AllCompletedAchievements::const_iterator itr = m_allCompletedAchievements.find(achievement->ID);
if (itr == m_allCompletedAchievements.end())
return false;
if (achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)
return itr->second != instanceId;
return true;
}
void SetRealmCompleted(AchievementEntry const* achievement)
void SetRealmCompleted(AchievementEntry const* achievement, uint32 instanceId)
{
m_allCompletedAchievements.insert(achievement->ID);
if (IsRealmCompleted(achievement, instanceId))
return;
m_allCompletedAchievements[achievement->ID] = instanceId;
}
// Removes instanceId as valid id to complete realm first kill achievements
void OnInstanceDestroyed(uint32 instanceId);
void LoadAchievementCriteriaList();
void LoadAchievementCriteriaData();
void LoadAchievementReferenceList();
@@ -387,7 +400,7 @@ class AchievementGlobalMgr
// store achievements by referenced achievement id to speed up lookup
AchievementListByReferencedId m_AchievementListByReferencedId;
typedef std::set<uint32> AllCompletedAchievements;
typedef std::map<uint32 /*achievementId*/, uint32 /*instanceId*/> AllCompletedAchievements;
AllCompletedAchievements m_allCompletedAchievements;
AchievementRewards m_achievementRewards;

View File

@@ -36,6 +36,7 @@
#include "Player.h"
#include "WorldSession.h"
#include "Opcodes.h"
#include "AchievementMgr.h"
MapManager::MapManager()
{
@@ -393,4 +394,5 @@ void MapManager::FreeInstanceId(uint32 instanceId)
SetNextInstanceId(instanceId);
_instanceIds[instanceId] = false;
sAchievementMgr->OnInstanceDestroyed(instanceId);
}