diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 3cb56dc7e..690ea9dc3 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -90,6 +90,14 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri { Field *fields = criteriaResult->Fetch(); CriteriaProgress *progress = new CriteriaProgress(fields[0].GetUInt32(), fields[1].GetUInt32(), fields[2].GetUInt64()); + + AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(progress->id); + if(!criteria || + criteria->timeLimit && progress->date + criteria->timeLimit < time(NULL)) + { + delete progress; + continue; + } m_criteriaProgress[progress->id] = progress; } while(criteriaResult->NextRow()); delete criteriaResult; @@ -305,6 +313,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) SetCriteriaProgress(achievementCriteria, 1); break; + case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + if(achievementCriteria->use_item.itemID != miscvalue1) + continue; + SetCriteriaProgress(achievementCriteria, 1, true); + break; } if(IsCompletedCriteria(achievementCriteria)) CompletedCriteria(achievementCriteria); @@ -377,6 +393,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return progress->counter >= achievementCriteria->fall_without_dying.fallHeight; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: return progress->counter >= 1; + case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: + return progress->counter >= achievementCriteria->use_item.itemCount; // handle all statistic-only criteria here case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: @@ -448,6 +466,16 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, return; progress->counter = newValue; } + if(entry->timeLimit) + { + time_t now = time(NULL); + if(progress->date + entry->timeLimit < now) + { + progress->counter = 1; + } + // also it seems illogical, the timeframe will be extended at every criteria update + progress->date = now; + } SendCriteriaUpdate(progress); } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index c41bc519c..888bf8757 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2081,6 +2081,9 @@ void Spell::cast(bool skipCheck) // set to real guid to be sent later to the client m_targets.updateTradeSlotItem(); + if(m_CastItem && m_caster->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); + // CAST SPELL SendSpellCooldown(); diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h index 83cd83d40..ebe0e6ae1 100644 --- a/src/shared/Database/DBCEnums.h +++ b/src/shared/Database/DBCEnums.h @@ -36,6 +36,7 @@ enum AchievementFlags { ACHIEVEMENT_FLAG_COUNTER = 0x00000001, ACHIEVEMENT_FLAG_REACH_LEVEL = 0x00000004, + ACHIEVEMENT_FLAG_RERERED_MAX = 0x00000010, // displays the maximum criteria of a refered achievement ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, ACHIEVEMENT_FLAG_REALM_FIRST_REACH= 0x00000100, ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index ab5ef29f3..4aa97397c 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -52,7 +52,7 @@ struct AchievementEntry //char *unk1[16]; // 43-58 //uint32 unk_flags; // 59 //uint32 count; // 60 - //uint32 refAchievement; // 61 + uint32 refAchievement; // 61 }; struct AchievementCategoryEntry diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index c465cf372..a80a94ace 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxxx"; +const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxxi"; const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix"; const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx"; const char AreaTriggerEntryfmt[]="niffffffff";