[11945] Fix a bunch of counter achievements. Some still require more work

Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
Schmoozerd 2012-04-10 19:54:28 +02:00
parent f09fa8d245
commit 43dd16ff60
4 changed files with 136 additions and 94 deletions

View file

@ -577,11 +577,11 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
progress.changed = false;
progress.timedCriteriaFailed = false;
AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement);
// A failed achievement will be removed on next tick - TODO: Possible that timer 2 is reseted
if (criteria->timeLimit)
{
AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement);
// Add not-completed achievements to time map
if (!IsCompletedCriteria(criteria, achievement))
{
@ -594,7 +594,7 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
}
// check intergiry with max allowed counter value
if (uint32 maxcounter = GetCriteriaProgressMaxCounter(criteria))
if (uint32 maxcounter = GetCriteriaProgressMaxCounter(criteria, achievement))
{
if (progress.counter > maxcounter)
{
@ -1699,98 +1699,141 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
}
}
uint32 AchievementMgr::GetCriteriaProgressMaxCounter(AchievementCriteriaEntry const* achievementCriteria)
uint32 AchievementMgr::GetCriteriaProgressMaxCounter(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
{
switch(achievementCriteria->requiredType)
uint32 resultValue = 0;
switch (achievementCriteria->requiredType)
{
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
return achievementCriteria->win_bg.winCount;
resultValue = achievementCriteria->win_bg.winCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
return achievementCriteria->kill_creature.creatureCount;
resultValue = achievementCriteria->kill_creature.creatureCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
return achievementCriteria->reach_level.level;
resultValue = achievementCriteria->reach_level.level;
break;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
return achievementCriteria->reach_skill_level.skillLevel;
resultValue = achievementCriteria->reach_skill_level.skillLevel;
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
return 1;
resultValue = 1;
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
return achievementCriteria->complete_quest_count.totalQuestCount;
resultValue = achievementCriteria->complete_quest_count.totalQuestCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
return achievementCriteria->complete_quests_in_zone.questCount;
resultValue = achievementCriteria->complete_quests_in_zone.questCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
return achievementCriteria->healing_done.count;
resultValue = achievementCriteria->healing_done.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
return achievementCriteria->complete_daily_quest.questCount;
resultValue = achievementCriteria->complete_daily_quest.questCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
return achievementCriteria->fall_without_dying.fallHeight;
resultValue = achievementCriteria->fall_without_dying.fallHeight;
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
return 1;
resultValue = 1;
break;
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
return achievementCriteria->be_spell_target.spellCount;
resultValue = achievementCriteria->be_spell_target.spellCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
return achievementCriteria->cast_spell.castCount;
resultValue = achievementCriteria->cast_spell.castCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
return 1;
resultValue = 1;
break;
case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
return achievementCriteria->own_item.itemCount;
resultValue = achievementCriteria->own_item.itemCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
return achievementCriteria->win_rated_arena.count;
resultValue = achievementCriteria->win_rated_arena.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
return achievementCriteria->learn_skill_level.skillLevel * 75;
resultValue = achievementCriteria->learn_skill_level.skillLevel * 75;
break;
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
return achievementCriteria->use_item.itemCount;
resultValue = achievementCriteria->use_item.itemCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
return achievementCriteria->loot_item.itemCount;
resultValue = achievementCriteria->loot_item.itemCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
return 1;
resultValue = 1;
break;
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
return achievementCriteria->buy_bank_slot.numberOfSlots;
resultValue = achievementCriteria->buy_bank_slot.numberOfSlots;
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
return achievementCriteria->gain_reputation.reputationAmount;
resultValue = achievementCriteria->gain_reputation.reputationAmount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
return achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions;
resultValue = achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions;
break;
case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
return achievementCriteria->visit_barber.numberOfVisits;
resultValue = achievementCriteria->visit_barber.numberOfVisits;
break;
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
return achievementCriteria->equip_epic_item.count;
resultValue = achievementCriteria->equip_epic_item.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
return achievementCriteria->roll_greed_on_loot.count;
resultValue = achievementCriteria->roll_greed_on_loot.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
return achievementCriteria->hk_class.count;
resultValue = achievementCriteria->hk_class.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
return achievementCriteria->hk_race.count;
resultValue = achievementCriteria->hk_race.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
return achievementCriteria->do_emote.count;
resultValue = achievementCriteria->do_emote.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
return achievementCriteria->equip_item.count;
resultValue = achievementCriteria->equip_item.count;
break;
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
return achievementCriteria->quest_reward_money.goldInCopper;
resultValue = achievementCriteria->quest_reward_money.goldInCopper;
break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
return achievementCriteria->loot_money.goldInCopper;
resultValue = achievementCriteria->loot_money.goldInCopper;
break;
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
return achievementCriteria->use_gameobject.useCount;
resultValue = achievementCriteria->use_gameobject.useCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
return achievementCriteria->special_pvp_kill.killCount;
resultValue = achievementCriteria->special_pvp_kill.killCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
return achievementCriteria->fish_in_gameobject.lootCount;
resultValue = achievementCriteria->fish_in_gameobject.lootCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
return 1;
resultValue = 1;
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
return achievementCriteria->learn_skillline_spell.spellCount;
resultValue = achievementCriteria->learn_skillline_spell.spellCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
return achievementCriteria->win_duel.duelCount;
resultValue = achievementCriteria->win_duel.duelCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
return achievementCriteria->loot_type.lootTypeCount;
resultValue = achievementCriteria->loot_type.lootTypeCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
return achievementCriteria->learn_skill_line.spellCount;
resultValue = achievementCriteria->learn_skill_line.spellCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
return achievementCriteria->honorable_kill.killCount;
resultValue = achievementCriteria->honorable_kill.killCount;
break;
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING:
return achievementCriteria->highest_personal_rating.teamrating;
resultValue = achievementCriteria->highest_personal_rating.teamrating;
break;
// handle all statistic-only criteria here
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
@ -1825,44 +1868,44 @@ uint32 AchievementMgr::GetCriteriaProgressMaxCounter(AchievementCriteriaEntry co
case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED:
case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
return 0;
resultValue = 0;
break;
}
return 0;
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
resultValue = std::numeric_limits<uint32>::max();
return resultValue;
}
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement) const
{
// counter can never complete
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
return false;
if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
{
// someone on this realm has already completed that achievement
if(sAchievementMgr.IsRealmCompleted(achievement))
if (sAchievementMgr.IsRealmCompleted(achievement))
return false;
}
CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID);
if(itr == m_criteriaProgress.end())
if (itr == m_criteriaProgress.end())
return false;
CriteriaProgress const* progress = &itr->second;
uint32 maxcounter = GetCriteriaProgressMaxCounter(achievementCriteria);
uint32 maxcounter = GetCriteriaProgressMaxCounter(achievementCriteria, achievement);
// different counters or non-completable criteria
if (!maxcounter)
return false;
return progress->counter >= maxcounter;
return progress->counter >= maxcounter || (achievement->flags & ACHIEVEMENT_FLAG_REQ_COUNT && progress->counter);
}
void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
{
// counter can never complete
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
return;
// already completed and stored
@ -1876,7 +1919,7 @@ void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
{
// counter can never complete
if(entry->flags & ACHIEVEMENT_FLAG_COUNTER)
if (entry->flags & ACHIEVEMENT_FLAG_COUNTER)
return false;
// for achievement with referenced achievement criterias get from referenced and counter from self
@ -1884,7 +1927,7 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
uint32 achievementForTestCount = entry->count;
AchievementCriteriaEntryList const* cList = sAchievementMgr.GetAchievementCriteriaByAchievement(achievementForTestId);
if(!cList)
if (!cList)
return false;
uint32 count = 0;
@ -1892,7 +1935,7 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
// Oddly, the target count is NOT countained in the achievement, but in each individual criteria
if (entry->flags & ACHIEVEMENT_FLAG_SUMM)
{
for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
for (AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
{
AchievementCriteriaEntry const* criteria = *itr;
@ -1912,25 +1955,25 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
// Default case - need complete all or
bool completed_all = true;
for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
for (AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
{
AchievementCriteriaEntry const* criteria = *itr;
bool completed = IsCompletedCriteria(criteria,entry);
bool completed = IsCompletedCriteria(criteria, entry);
// found an uncompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
if(completed)
if (completed)
++count;
else
completed_all = false;
// completed as have req. count of completed criterias
if(achievementForTestCount > 0 && achievementForTestCount <= count)
if (achievementForTestCount > 0 && achievementForTestCount <= count)
return true;
}
// all criterias completed requirement
if(completed_all && achievementForTestCount==0)
if (completed_all && achievementForTestCount == 0)
return true;
return false;
@ -1940,10 +1983,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* criteri
{
DETAIL_FILTER_LOG(LOG_FILTER_ACHIEVEMENT_UPDATES, "AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", criteria->ID, changeValue, m_player->GetGUIDLow());
uint32 max_value = GetCriteriaProgressMaxCounter(criteria);
if (!max_value)
max_value = std::numeric_limits<uint32>::max();
uint32 max_value = GetCriteriaProgressMaxCounter(criteria, achievement);
// change value must be in allowed value range for SET/HIGHEST directly
if (changeValue > max_value)
@ -1954,10 +1994,10 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* criteri
uint32 newValue = 0;
CriteriaProgressMap::iterator iter = m_criteriaProgress.find(criteria->ID);
if(iter == m_criteriaProgress.end())
if (iter == m_criteriaProgress.end())
{
// not create record for 0 counter
if(changeValue == 0)
if (changeValue == 0)
return;
// not start manually started timed achievements
@ -2001,7 +2041,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* criteri
}
// not update (not mark as changed) if counter will have same value
if(progress->counter == newValue)
if (progress->counter == newValue)
return;
}
@ -2009,16 +2049,12 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* criteri
progress->changed = true;
// update client side value
SendCriteriaUpdate(criteria->ID,progress);
// nothing do for counter case
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
return;
SendCriteriaUpdate(criteria->ID, progress);
// update dependent achievements state at criteria complete
if (old_value < progress->counter)
{
if(IsCompletedCriteria(criteria, achievement))
if (IsCompletedCriteria(criteria, achievement))
CompletedCriteriaFor(achievement);
// check again the completeness for SUMM and REQ COUNT achievements,
@ -2029,10 +2065,10 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* criteri
CompletedAchievement(achievement);
}
if(AchievementEntryList const* achRefList = sAchievementMgr.GetAchievementByReferencedId(achievement->ID))
if (AchievementEntryList const* achRefList = sAchievementMgr.GetAchievementByReferencedId(achievement->ID))
{
for(AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
if(IsCompletedAchievement(*itr))
for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
if (IsCompletedAchievement(*itr))
CompletedAchievement(*itr);
}
}
@ -2047,13 +2083,13 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* criteri
}
if (HasAchievement(achievement->ID))
if(!IsCompletedAchievement(achievement))
if (!IsCompletedAchievement(achievement))
IncompletedAchievement(achievement);
if(AchievementEntryList const* achRefList = sAchievementMgr.GetAchievementByReferencedId(achievement->ID))
for(AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
if (AchievementEntryList const* achRefList = sAchievementMgr.GetAchievementByReferencedId(achievement->ID))
for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
if (HasAchievement((*itr)->ID))
if(!IsCompletedAchievement(*itr))
if (!IsCompletedAchievement(*itr))
IncompletedAchievement(*itr);
}
}

View file

@ -287,7 +287,7 @@ class AchievementMgr
return iter != m_criteriaProgress.end() ? iter->second.counter : 0;
}
static uint32 GetCriteriaProgressMaxCounter(AchievementCriteriaEntry const* entry);
static uint32 GetCriteriaProgressMaxCounter(AchievementCriteriaEntry const* entry, AchievementEntry const* achievement);
// Use PROGRESS_SET only for reset/downgrade criteria progress
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST };

View file

@ -1243,7 +1243,7 @@ void ChatHandler::ShowAchievementCriteriaListHelper(AchievementCriteriaEntry con
ss << GetMangosString(LANG_COUNTER);
else
{
ss << " [" << AchievementMgr::GetCriteriaProgressMaxCounter(criEntry) << "]";
ss << " [" << AchievementMgr::GetCriteriaProgressMaxCounter(criEntry, achEntry) << "]";
if (target && target->GetAchievementMgr().IsCompletedCriteria(criEntry, achEntry))
ss << GetMangosString(LANG_COMPLETE);
@ -1323,7 +1323,9 @@ bool ChatHandler::HandleAchievementAddCommand(char* args)
if (mgr.IsCompletedCriteria(*itr, achEntry))
continue;
uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(*itr);
uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(*itr, achEntry);
if (maxValue == std::numeric_limits<uint32>::max())
maxValue = 1; // Exception for counter like achievements, set them only to 1
mgr.SetCriteriaProgress(*itr, achEntry, maxValue, AchievementMgr::PROGRESS_SET);
}
}
@ -1398,7 +1400,9 @@ bool ChatHandler::HandleAchievementCriteriaAddCommand(char* args)
LocaleConstant loc = GetSessionDbcLocale();
uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(criEntry);
uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(criEntry, achEntry);
if (maxValue == std::numeric_limits<uint32>::max())
maxValue = 1; // Exception for counter like achievements, set them only to 1
AchievementMgr& mgr = target->GetAchievementMgr();
@ -1463,7 +1467,9 @@ bool ChatHandler::HandleAchievementCriteriaRemoveCommand(char* args)
LocaleConstant loc = GetSessionDbcLocale();
uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(criEntry);
uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(criEntry, achEntry);
if (maxValue == std::numeric_limits<uint32>::max())
maxValue = 1; // Exception for counter like achievements, set them only to 1
AchievementMgr& mgr = target->GetAchievementMgr();

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11944"
#define REVISION_NR "11945"
#endif // __REVISION_NR_H__