diff options
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.cpp | 64 | ||||
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 3 |
3 files changed, 53 insertions, 17 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index e30f6ed35df..41b9acfff2c 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -873,6 +873,36 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui SetCriteriaProgress(achievementCriteria, counter); break; } + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: + { + time_t nextDailyResetTime = sWorld.GetNextDailyQuestsResetTime(); + CriteriaProgress *progress = GetCriteriaProgress(achievementCriteria); + + if (!miscvalue1) // Login case. + { + // reset if player missed one day. + if (progress && progress->date < (nextDailyResetTime - 2 * DAY)) + SetCriteriaProgress(achievementCriteria, 0, PROGRESS_SET); + continue; + } + + ProgressType progressType; + if (!progress) + // 1st time. Start count. + progressType = PROGRESS_SET; + else if (progress->date < (nextDailyResetTime - 2 * DAY)) + // last progress is older than 2 days. Player missed 1 day => Retart count. + progressType = PROGRESS_SET; + else if (progress->date < (nextDailyResetTime - DAY)) + // last progress is between 1 and 2 days. => 1st time of the day. + progressType = PROGRESS_ACCUMULATE; + else + // last progress is within the day before the reset => Already counted today. + continue; + + SetCriteriaProgress(achievementCriteria, 1, progressType); + break; + } case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: { // speedup for non-login case @@ -1428,7 +1458,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING: break; // FIXME: not triggered in code as result, need to implement - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: @@ -1483,11 +1512,10 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return false; } - CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID); - if (itr == m_criteriaProgress.end()) + CriteriaProgress const* progress = GetCriteriaProgress(achievementCriteria); + if (!progress) return false; - CriteriaProgress const* progress = &itr->second; switch(achievementCriteria->requiredType) { @@ -1516,6 +1544,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return progress->counter >= 1; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: return progress->counter >= achievementCriteria->complete_quest_count.totalQuestCount; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: + return progress->counter >= achievementCriteria->complete_daily_quest_daily.numberOfDays; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount; case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: @@ -1661,11 +1691,10 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) { AchievementCriteriaEntry const* criteria = *itr; - CriteriaProgressMap::const_iterator itrProgress = m_criteriaProgress.find(criteria->ID); - if (itrProgress == m_criteriaProgress.end()) + CriteriaProgress const* progress = GetCriteriaProgress(criteria); + if (!progress) continue; - CriteriaProgress const* progress = &itrProgress->second; count += progress->counter; // for counters, field4 contains the main count requirement @@ -1701,6 +1730,16 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) return false; } +CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry const* entry) +{ + CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); + + if (iter == m_criteriaProgress.end()) + return NULL; + + return &(iter->second); +} + void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype) { // Don't allow to cheat - doing timed achievements without timer active @@ -1711,11 +1750,8 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, if ((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES) == 0) sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow()); - CriteriaProgress *progress = NULL; - - CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); - - if (iter == m_criteriaProgress.end()) + CriteriaProgress* progress = GetCriteriaProgress(entry); + if (!progress) { // not create record for 0 counter but allow it for timed achievements // we will need to send 0 progress to client to start the timer @@ -1724,12 +1760,9 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, progress = &m_criteriaProgress[entry->ID]; progress->counter = changeValue; - progress->date = time(NULL); } else { - progress = &iter->second; - uint32 newValue = 0; switch(ptype) { @@ -1756,6 +1789,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, } progress->changed = true; + progress->date = time(NULL); // set the date to the latest update. uint32 timeElapsed = 0; bool timedCompleted = false; diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index 6e27a3da068..97dbc86396e 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -36,7 +36,7 @@ typedef std::map<uint32,AchievementEntryList> AchievementListByReference struct CriteriaProgress { uint32 counter; - time_t date; + time_t date; // latest update time. bool changed; }; @@ -258,6 +258,7 @@ class AchievementMgr 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); + CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry); void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET); void CompletedCriteriaFor(AchievementEntry const* achievement); bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 56068408c9f..a6dc7ab137e 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14316,7 +14316,8 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver, if (pQuest->IsDaily()) { SetDailyQuestStatus(quest_id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id); } if (pQuest->IsWeekly()) |