mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[7607] Improvements in support some generic achievement classes
* Implement support achievements with refAchievement field != 0, that have criterias stored in achievement refAchievement. * Implement support achievement complete req. with specific count of completed critirias. * Avoid full achievement list scan at search achievement associated with criteria.
This commit is contained in:
parent
6c6703f363
commit
0c2f74bb02
6 changed files with 121 additions and 53 deletions
|
|
@ -407,21 +407,21 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||||
{
|
{
|
||||||
AchievementCriteriaEntry const *achievementCriteria = (*i);
|
AchievementCriteriaEntry const *achievementCriteria = (*i);
|
||||||
|
|
||||||
// don't update already completed criteria
|
if (achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup())
|
||||||
if(IsCompletedCriteria(achievementCriteria))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
||||||
if(!achievement)
|
if (!achievement)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE) ||
|
if ((achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE) ||
|
||||||
(achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
|
(achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// don't update already completed criteria
|
||||||
|
if (IsCompletedCriteria(achievementCriteria,achievement))
|
||||||
|
continue;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
// std. case: increment at 1
|
// std. case: increment at 1
|
||||||
|
|
@ -955,20 +955,24 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL:
|
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL:
|
||||||
break; // Not implemented yet :(
|
break; // Not implemented yet :(
|
||||||
}
|
}
|
||||||
if(IsCompletedCriteria(achievementCriteria))
|
if(IsCompletedCriteria(achievementCriteria,achievement))
|
||||||
CompletedCriteria(achievementCriteria);
|
CompletedCriteria(achievementCriteria,achievement);
|
||||||
|
|
||||||
|
|
||||||
|
if(AchievementEntryList const* achRefList = achievementmgr.GetAchievementByReferencedId(achievement->ID))
|
||||||
|
{
|
||||||
|
for(AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
|
||||||
|
if(IsCompletedAchievement(*itr))
|
||||||
|
CompletedAchievement(*itr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32 achievIdByClass[MAX_CLASSES] = { 0, 459, 465 , 462, 458, 464, 461, 467, 460, 463, 0, 466 };
|
static const uint32 achievIdByClass[MAX_CLASSES] = { 0, 459, 465 , 462, 458, 464, 461, 467, 460, 463, 0, 466 };
|
||||||
static const uint32 achievIdByRace[MAX_RACES] = { 0, 1408, 1410, 1407, 1409, 1413, 1411, 1404, 1412, 0, 1405, 1406 };
|
static const uint32 achievIdByRace[MAX_RACES] = { 0, 1408, 1410, 1407, 1409, 1413, 1411, 1404, 1412, 0, 1405, 1406 };
|
||||||
|
|
||||||
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria)
|
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
|
||||||
{
|
{
|
||||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
|
||||||
if(!achievement)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// counter can never complete
|
// counter can never complete
|
||||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1083,45 +1087,64 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria)
|
void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement)
|
||||||
{
|
{
|
||||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement);
|
|
||||||
if(!achievement)
|
|
||||||
return;
|
|
||||||
// counter can never complete
|
// counter can never complete
|
||||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL || GetAchievementCompletionState(achievement)==ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED)
|
// already completed and stored
|
||||||
{
|
if (m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((criteria->referredAchievement==achievement->ID && (criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)) ||
|
||||||
|
IsCompletedAchievement(achievement))
|
||||||
CompletedAchievement(achievement);
|
CompletedAchievement(achievement);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: achievement 705 requires 4 criteria to be fulfilled
|
// TODO: achievement 705 requires 4 criteria to be fulfilled
|
||||||
AchievementCompletionState AchievementMgr::GetAchievementCompletionState(AchievementEntry const* entry)
|
bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
|
||||||
{
|
{
|
||||||
if(m_completedAchievements.find(entry->ID)!=m_completedAchievements.end())
|
// for achievement with referenced achievement criterias get from referenced and counter from self
|
||||||
return ACHIEVEMENT_COMPLETED_COMPLETED_STORED;
|
uint32 achievmentForTestId = entry->refAchievement ? entry->refAchievement : entry->ID;
|
||||||
|
uint32 achievmentForTestCount = entry->count;
|
||||||
|
|
||||||
bool foundOutstanding = false;
|
AchievementCriteriaEntryList const* cList = achievementmgr.GetAchievementCriteriaByAchievement(achievmentForTestId);
|
||||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
if(!cList)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 count = 0;
|
||||||
|
bool completed_all = true;
|
||||||
|
|
||||||
|
for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
|
||||||
{
|
{
|
||||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
|
AchievementCriteriaEntry const* criteria = *itr;
|
||||||
if(!criteria || criteria->referredAchievement!= entry->ID)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(IsCompletedCriteria(criteria) && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
|
bool completed = IsCompletedCriteria(criteria,entry);
|
||||||
return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
|
|
||||||
|
|
||||||
// found an umcompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
|
// found an uncompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
|
||||||
if(!IsCompletedCriteria(criteria))
|
if(completed)
|
||||||
foundOutstanding = true;
|
++count;
|
||||||
|
else
|
||||||
|
completed_all = false;
|
||||||
|
|
||||||
|
if(achievmentForTestId == entry->ID) // not referenced achievement
|
||||||
|
{
|
||||||
|
// completed as single req. criteria
|
||||||
|
if(completed && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// completed as have req. count of completed criterias
|
||||||
|
if(achievmentForTestCount > 0 && achievmentForTestCount <= count)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if(foundOutstanding)
|
|
||||||
return ACHIEVEMENT_COMPLETED_NONE;
|
// all criterias completed requirement
|
||||||
else
|
if(completed_all && achievmentForTestCount==0)
|
||||||
return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
|
void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
|
||||||
|
|
@ -1317,7 +1340,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
||||||
}
|
}
|
||||||
|
|
||||||
barGoLink bar( sAchievementCriteriaStore.GetNumRows() );
|
barGoLink bar( sAchievementCriteriaStore.GetNumRows() );
|
||||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
|
||||||
{
|
{
|
||||||
bar.step();
|
bar.step();
|
||||||
|
|
||||||
|
|
@ -1326,12 +1349,42 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
|
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
|
||||||
|
m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString(">> Loaded %lu achievement criteria.",(unsigned long)m_AchievementCriteriasByType->size());
|
sLog.outString(">> Loaded %lu achievement criteria.",(unsigned long)m_AchievementCriteriasByType->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AchievementGlobalMgr::LoadAchievementReferenceList()
|
||||||
|
{
|
||||||
|
if(sAchievementStore.GetNumRows()==0)
|
||||||
|
{
|
||||||
|
barGoLink bar(1);
|
||||||
|
bar.step();
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outErrorDb(">> Loaded 0 achievement references.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 count = 0;
|
||||||
|
barGoLink bar( sAchievementStore.GetNumRows() );
|
||||||
|
for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId)
|
||||||
|
{
|
||||||
|
bar.step();
|
||||||
|
|
||||||
|
AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId);
|
||||||
|
if(!achievement || !achievement->refAchievement)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_AchievementListByReferencedId[achievement->refAchievement].push_back(achievement);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded %u achievement references.",count);
|
||||||
|
}
|
||||||
|
|
||||||
void AchievementGlobalMgr::LoadCompletedAchievements()
|
void AchievementGlobalMgr::LoadCompletedAchievements()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,11 @@
|
||||||
#define CRITERIA_CAST_SPELL_REQ_COUNT 46
|
#define CRITERIA_CAST_SPELL_REQ_COUNT 46
|
||||||
#define ACHIEVEMENT_REWARD_COUNT 57
|
#define ACHIEVEMENT_REWARD_COUNT 57
|
||||||
|
|
||||||
typedef std::list<const AchievementCriteriaEntry*> AchievementCriteriaEntryList;
|
typedef std::list<AchievementCriteriaEntry const*> AchievementCriteriaEntryList;
|
||||||
|
typedef std::list<AchievementEntry const*> AchievementEntryList;
|
||||||
|
|
||||||
|
typedef std::map<uint32,AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
|
||||||
|
typedef std::map<uint32,AchievementEntryList> AchievementListByReferencedId;
|
||||||
|
|
||||||
struct CriteriaProgress
|
struct CriteriaProgress
|
||||||
{
|
{
|
||||||
|
|
@ -80,13 +84,6 @@ class Unit;
|
||||||
class Player;
|
class Player;
|
||||||
class WorldPacket;
|
class WorldPacket;
|
||||||
|
|
||||||
enum AchievementCompletionState
|
|
||||||
{
|
|
||||||
ACHIEVEMENT_COMPLETED_NONE,
|
|
||||||
ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED,
|
|
||||||
ACHIEVEMENT_COMPLETED_COMPLETED_STORED,
|
|
||||||
};
|
|
||||||
|
|
||||||
class AchievementMgr
|
class AchievementMgr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -108,10 +105,11 @@ class AchievementMgr
|
||||||
void SendAchievementEarned(AchievementEntry const* achievement);
|
void SendAchievementEarned(AchievementEntry const* achievement);
|
||||||
void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress);
|
void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress);
|
||||||
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
|
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
|
||||||
void CompletedCriteria(AchievementCriteriaEntry const* entry);
|
void CompletedCriteria(AchievementCriteriaEntry const* entry, AchievementEntry const* achievement);
|
||||||
void CompletedAchievement(AchievementEntry const* entry);
|
void CompletedAchievement(AchievementEntry const* entry);
|
||||||
bool IsCompletedCriteria(AchievementCriteriaEntry const* entry);
|
bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
|
||||||
AchievementCompletionState GetAchievementCompletionState(AchievementEntry const* entry);
|
bool IsCompletedAchievement(AchievementEntry const* entry);
|
||||||
|
void CompleteAchievementsWithRefs(AchievementEntry const* entry);
|
||||||
void BuildAllDataPacket(WorldPacket *data);
|
void BuildAllDataPacket(WorldPacket *data);
|
||||||
|
|
||||||
Player* m_player;
|
Player* m_player;
|
||||||
|
|
@ -123,6 +121,17 @@ class AchievementGlobalMgr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
||||||
|
AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id)
|
||||||
|
{
|
||||||
|
AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
|
||||||
|
return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AchievementEntryList const* GetAchievementByReferencedId(uint32 id) const
|
||||||
|
{
|
||||||
|
AchievementListByReferencedId::const_iterator itr = m_AchievementListByReferencedId.find(id);
|
||||||
|
return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const
|
AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const
|
||||||
{
|
{
|
||||||
|
|
@ -156,6 +165,7 @@ class AchievementGlobalMgr
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadAchievementCriteriaList();
|
void LoadAchievementCriteriaList();
|
||||||
|
void LoadAchievementReferenceList();
|
||||||
void LoadCompletedAchievements();
|
void LoadCompletedAchievements();
|
||||||
void LoadRewards();
|
void LoadRewards();
|
||||||
void LoadRewardLocales();
|
void LoadRewardLocales();
|
||||||
|
|
@ -164,6 +174,10 @@ class AchievementGlobalMgr
|
||||||
|
|
||||||
// store achievement criterias by type to speed up lookup
|
// store achievement criterias by type to speed up lookup
|
||||||
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
||||||
|
// store achievement criterias by achievement to speed up lookup
|
||||||
|
AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
|
||||||
|
// store achievements by referenced achievement id to speed up lookup
|
||||||
|
AchievementListByReferencedId m_AchievementListByReferencedId;
|
||||||
|
|
||||||
typedef std::set<uint32> AllCompletedAchievements;
|
typedef std::set<uint32> AllCompletedAchievements;
|
||||||
AllCompletedAchievements m_allCompletedAchievements;
|
AllCompletedAchievements m_allCompletedAchievements;
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,8 @@ struct AchievementEntry
|
||||||
//uint32 icon; // 42 icon (from SpellIcon.dbc)
|
//uint32 icon; // 42 icon (from SpellIcon.dbc)
|
||||||
//char *titleReward[16]; // 43-58
|
//char *titleReward[16]; // 43-58
|
||||||
//uint32 titleReward_flags; // 59
|
//uint32 titleReward_flags; // 59
|
||||||
//uint32 count; // 60 - need this count Criteria for complete
|
uint32 count; // 60 - need this count of completed criterias (own or referenced achievement criterias)
|
||||||
uint32 refAchievement; // 61 - related achievement?
|
uint32 refAchievement; // 61 - referenced achievement (counting of all completed criterias)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AchievementCategoryEntry
|
struct AchievementCategoryEntry
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#ifndef MANGOS_DBCSFRM_H
|
#ifndef MANGOS_DBCSFRM_H
|
||||||
#define MANGOS_DBCSFRM_H
|
#define MANGOS_DBCSFRM_H
|
||||||
|
|
||||||
const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxxi";
|
const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
|
||||||
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
|
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
|
||||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
||||||
const char AreaGroupEntryfmt[]="niiiiiii";
|
const char AreaGroupEntryfmt[]="niiiiiii";
|
||||||
|
|
|
||||||
|
|
@ -1265,6 +1265,7 @@ void World::SetInitialWorldSettings()
|
||||||
|
|
||||||
sLog.outString( "Loading Achievements..." );
|
sLog.outString( "Loading Achievements..." );
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
|
achievementmgr.LoadAchievementReferenceList();
|
||||||
achievementmgr.LoadAchievementCriteriaList();
|
achievementmgr.LoadAchievementCriteriaList();
|
||||||
achievementmgr.LoadRewards();
|
achievementmgr.LoadRewards();
|
||||||
achievementmgr.LoadRewardLocales();
|
achievementmgr.LoadRewardLocales();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7606"
|
#define REVISION_NR "7607"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue