Implemented ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM

Added basic support for timed achievements
This commit is contained in:
arrai 2008-11-04 00:52:42 +01:00
parent 5114c17da2
commit 3d86187c4a
5 changed files with 34 additions and 2 deletions

View file

@ -90,6 +90,14 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
{ {
Field *fields = criteriaResult->Fetch(); Field *fields = criteriaResult->Fetch();
CriteriaProgress *progress = new CriteriaProgress(fields[0].GetUInt32(), fields[1].GetUInt32(), fields[2].GetUInt64()); 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; m_criteriaProgress[progress->id] = progress;
} while(criteriaResult->NextRow()); } while(criteriaResult->NextRow());
delete criteriaResult; delete criteriaResult;
@ -305,6 +313,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
SetCriteriaProgress(achievementCriteria, 1); SetCriteriaProgress(achievementCriteria, 1);
break; 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)) if(IsCompletedCriteria(achievementCriteria))
CompletedCriteria(achievementCriteria); CompletedCriteria(achievementCriteria);
@ -377,6 +393,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->fall_without_dying.fallHeight; return progress->counter >= achievementCriteria->fall_without_dying.fallHeight;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
return progress->counter >= 1; return progress->counter >= 1;
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
return progress->counter >= achievementCriteria->use_item.itemCount;
// handle all statistic-only criteria here // handle all statistic-only criteria here
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
@ -448,6 +466,16 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
return; return;
progress->counter = newValue; 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); SendCriteriaUpdate(progress);
} }

View file

@ -2081,6 +2081,9 @@ void Spell::cast(bool skipCheck)
// set to real guid to be sent later to the client // set to real guid to be sent later to the client
m_targets.updateTradeSlotItem(); 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 // CAST SPELL
SendSpellCooldown(); SendSpellCooldown();

View file

@ -36,6 +36,7 @@ enum AchievementFlags
{ {
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, ACHIEVEMENT_FLAG_COUNTER = 0x00000001,
ACHIEVEMENT_FLAG_REACH_LEVEL = 0x00000004, ACHIEVEMENT_FLAG_REACH_LEVEL = 0x00000004,
ACHIEVEMENT_FLAG_RERERED_MAX = 0x00000010, // displays the maximum criteria of a refered achievement
ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, ACHIEVEMENT_FLAG_AVERAGE = 0x00000040,
ACHIEVEMENT_FLAG_REALM_FIRST_REACH= 0x00000100, ACHIEVEMENT_FLAG_REALM_FIRST_REACH= 0x00000100,
ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200,

View file

@ -52,7 +52,7 @@ struct AchievementEntry
//char *unk1[16]; // 43-58 //char *unk1[16]; // 43-58
//uint32 unk_flags; // 59 //uint32 unk_flags; // 59
//uint32 count; // 60 //uint32 count; // 60
//uint32 refAchievement; // 61 uint32 refAchievement; // 61
}; };
struct AchievementCategoryEntry struct AchievementCategoryEntry

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx"; const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
const char AreaTriggerEntryfmt[]="niffffffff"; const char AreaTriggerEntryfmt[]="niffffffff";