Core/Achievements:

Implemented map and group requirements for achievements
Changed possible methods to const
Implemented hidden flag for achievement criteria
This commit is contained in:
Shauren
2011-03-04 12:11:20 +01:00
parent 7a0df5876b
commit 704491101f
4 changed files with 88 additions and 61 deletions
+55 -37
View File
@@ -622,13 +622,13 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
}
}
void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const
{
if (GetPlayer()->GetSession()->PlayerLoading())
return;
// Don't send for achievements with ACHIEVEMENT_FLAG_TRACKING
if (achievement->flags & ACHIEVEMENT_FLAG_TRACKING)
if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN)
return;
#ifdef TRINITY_DEBUG
@@ -661,9 +661,9 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID);
Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> say_do(say_builder);
Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetPlayer(),sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do);
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker);
cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
@@ -676,7 +676,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
GetPlayer()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
}
void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted)
void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const
{
WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
data << uint32(entry->ID);
@@ -731,19 +731,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
AchievementCriteriaEntry const *achievementCriteria = (*i);
if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, achievementCriteria->ID, NULL))
continue;
AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
if (!achievement)
continue;
if ((achievement->factionFlag == ACHIEVEMENT_FACTION_HORDE && GetPlayer()->GetTeam() != HORDE) ||
(achievement->factionFlag == ACHIEVEMENT_FACTION_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
continue;
// don't update already completed criteria
if (IsCompletedCriteria(achievementCriteria,achievement))
if (!CanUpdateCriteria(achievementCriteria, achievement))
continue;
switch (type)
@@ -1527,23 +1519,19 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break; // Not implemented yet :(
}
if (IsCompletedCriteria(achievementCriteria,achievement))
if (IsCompletedCriteria(achievementCriteria, achievement))
CompletedCriteriaFor(achievement);
// check again the completeness for SUMM and REQ COUNT achievements,
// as they don't depend on the completed criteria but on the sum of the progress of each individual criteria
if (achievement->flags & ACHIEVEMENT_FLAG_SUMM)
{
if (IsCompletedAchievement(achievement))
CompletedAchievement(achievement);
}
if (AchievementEntryList const* achRefList = sAchievementMgr->GetAchievementByReferencedId(achievement->ID))
{
for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
if (IsCompletedAchievement(*itr))
CompletedAchievement(*itr);
}
}
}
@@ -1567,7 +1555,6 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
if (!progress)
return false;
switch (achievementCriteria->requiredType)
{
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
@@ -2024,14 +2011,14 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement, b
}
}
void AchievementMgr::SendAllAchievementData()
void AchievementMgr::SendAllAchievementData() const
{
WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4);
BuildAllDataPacket(&data);
GetPlayer()->GetSession()->SendPacket(&data);
}
void AchievementMgr::SendRespondInspectAchievements(Player* player)
void AchievementMgr::SendRespondInspectAchievements(Player* player) const
{
WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 9+m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4);
data.append(GetPlayer()->GetPackGUID());
@@ -2042,14 +2029,14 @@ void AchievementMgr::SendRespondInspectAchievements(Player* player)
/**
* used by SMSG_RESPOND_INSPECT_ACHIEVEMENT and SMSG_ALL_ACHIEVEMENT_DATA
*/
void AchievementMgr::BuildAllDataPacket(WorldPacket *data)
void AchievementMgr::BuildAllDataPacket(WorldPacket *data) const
{
AchievementEntry const *achievement;
AchievementEntry const* achievement = NULL;
for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
{
// Skip tracking - they bug client UI
// Skip hidden achievements
achievement = sAchievementStore.LookupEntry(iter->first);
if (achievement->flags & ACHIEVEMENT_FLAG_TRACKING)
if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN)
continue;
*data << uint32(iter->first);
@@ -2057,8 +2044,13 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket *data)
}
*data << int32(-1);
AchievementCriteriaEntry const* criteria = NULL;
for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
{
criteria = sAchievementCriteriaStore.LookupEntry(iter->first);
if (criteria->flags & ACHIEVEMENT_CRITERIA_FLAG_HIDDEN)
continue;
*data << uint32(iter->first);
data->appendPackGUID(iter->second.counter);
data->append(GetPlayer()->GetPackGUID());
@@ -2076,17 +2068,43 @@ bool AchievementMgr::HasAchieved(AchievementEntry const* achievement) const
return m_completedAchievements.find(achievement->ID) != m_completedAchievements.end();
}
bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement)
{
if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL))
return false;
if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && GetPlayer()->GetTeam() != HORDE) ||
(achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
return false;
for (uint32 i = 0; i < MAX_CRITERIA_REQUIREMENTS; ++i)
{
if (!criteria->additionalRequrements[i].additionalRequirement_type)
continue;
switch (criteria->additionalRequrements[i].additionalRequirement_type)
{
case ACHIEVEMENT_CRITERIA_CONDITION_MAP:
if (GetPlayer()->GetMapId() != criteria->additionalRequrements[i].additionalRequirement_value)
return false;
break;
case ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP:
if (GetPlayer()->GetGroup())
return false;
break;
default:
break;
}
}
// don't update already completed criteria
if (IsCompletedCriteria(criteria, achievement))
return false;
return true;
}
//==========================================================
AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type)
{
return m_AchievementCriteriasByType[type];
}
AchievementCriteriaEntryList const& AchievementGlobalMgr::GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type)
{
return m_AchievementCriteriasByTimedType[type];
}
void AchievementGlobalMgr::LoadAchievementCriteriaList()
{
uint32 oldMSTime = getMSTime();
@@ -2364,7 +2382,7 @@ void AchievementGlobalMgr::LoadRewards()
continue;
}
if (pAchievement->factionFlag == ACHIEVEMENT_FACTION_ANY && ((reward.titleId[0] == 0) != (reward.titleId[1] == 0)))
if (pAchievement->requiredFaction == ACHIEVEMENT_FACTION_ANY && ((reward.titleId[0] == 0) != (reward.titleId[1] == 0)))
sLog->outErrorDb("Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) for only one team.", entry, reward.titleId[0], reward.titleId[1]);
if (reward.titleId[0])
+20 -12
View File
@@ -255,26 +255,26 @@ class AchievementMgr
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1 = 0, uint32 miscvalue2 = 0, Unit *unit = NULL, uint32 time = 0);
void CompletedAchievement(AchievementEntry const* entry, bool ignoreGMAllowAchievementConfig = false);
void CheckAllAchievementCriteria();
void SendAllAchievementData();
void SendRespondInspectAchievements(Player* player);
void SendAllAchievementData() const;
void SendRespondInspectAchievements(Player* player) const;
bool HasAchieved(AchievementEntry const* achievement) const;
Player* GetPlayer() { return m_player; }
Player* GetPlayer() const { return m_player; }
void UpdateTimedAchievements(uint32 timeDiff);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
private:
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST };
void SendAchievementEarned(AchievementEntry const* achievement);
void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted);
void SendAchievementEarned(AchievementEntry const* achievement) const;
void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const;
CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry);
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
void RemoveCriteriaProgress(AchievementCriteriaEntry const* entry);
void CompletedCriteriaFor(AchievementEntry const* achievement);
bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
bool IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement);
bool IsCompletedAchievement(AchievementEntry const* entry);
//void CompleteAchievementsWithRefs(AchievementEntry const* entry);
void BuildAllDataPacket(WorldPacket *data);
bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
void BuildAllDataPacket(WorldPacket *data) const;
Player* m_player;
CriteriaProgressMap m_criteriaProgress;
@@ -290,9 +290,17 @@ class AchievementGlobalMgr
~AchievementGlobalMgr() {}
public:
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type);
AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id)
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type) const
{
return m_AchievementCriteriasByType[type];
}
AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type) const
{
return m_AchievementCriteriasByTimedType[type];
}
AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id) const
{
AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL;
@@ -316,7 +324,7 @@ class AchievementGlobalMgr
return iter != m_achievementRewardLocales.end() ? &iter->second : NULL;
}
AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const *achievementCriteria)
AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const *achievementCriteria) const
{
AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID);
return iter != m_criteriaDataMap.end() ? &iter->second : NULL;
+11 -10
View File
@@ -58,7 +58,7 @@ enum AchievementFaction
enum AchievementFlags
{
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
ACHIEVEMENT_FLAG_TRACKING = 0x00000002, // Not sent to client - internal use only
ACHIEVEMENT_FLAG_HIDDEN = 0x00000002, // Not sent to client - internal use only
ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx"
ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value)
ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??)
@@ -73,19 +73,20 @@ enum AchievementFlags
enum AchievementCriteriaCondition
{
ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1, // reset progress on death
ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
ACHIEVEMENT_CRITERIA_CONDITION_MAP = 3, // requires you to be on specific map, reset at change
ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1, // reset progress on death
ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
ACHIEVEMENT_CRITERIA_CONDITION_MAP = 3, // requires you to be on specific map, reset at change
ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group
ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
};
enum AchievementCriteriaCompletionFlags
enum AchievementCriteriaFlags
{
ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar
ACHIEVEMENT_CRITERIA_FLAG_HIDE_CRITERIA = 0x00000002, // Not show criteria in client
ACHIEVEMENT_CRITERIA_FLAG_HIDDEN = 0x00000002, // Not show criteria in client
ACHIEVEMENT_CRITERIA_FLAG_UNK3 = 0x00000004, // BG related??
ACHIEVEMENT_CRITERIA_FLAG_UNK4 = 0x00000008, //
ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used
+2 -2
View File
@@ -42,7 +42,7 @@
struct AchievementEntry
{
uint32 ID; // 0
int32 factionFlag; // 1 -1=all, 0=horde, 1=alliance
int32 requiredFaction; // 1 -1=all, 0=horde, 1=alliance
int32 mapID; // 2 -1=none
//uint32 parentAchievement; // 3 its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin)
char *name[16]; // 4-19
@@ -501,7 +501,7 @@ struct AchievementCriteriaEntry
//char* name[16]; // 9-24
//uint32 name_flags; // 25
uint32 completionFlag; // 26
uint32 flags; // 26
uint32 timedType; // 27
uint32 timerStartEvent; // 28 Alway appears with timed events
// for timed spells it is spell id for