[10347] Fixed wrong ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION (46) check.

In result wrong check characters complete
exalted reputation achievements at create or any reputation change event
with negative reputation. Fix prevent new cases but not do anything with
already wrongly recieved ahcievements.

Also:
* Avoid use PROGRESS_SET at normal achievment criteria progress update
  becase achivement/counter in normal way can't decrease.
* At achievment criteria progress loading check that progress counter less
  or equal max counter value.
This commit is contained in:
VladimirMangos 2010-08-12 00:04:42 +04:00
parent 3c5da27442
commit b0d42a6f67
4 changed files with 41 additions and 30 deletions

View file

@ -604,6 +604,16 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
progress.counter = counter; progress.counter = counter;
progress.date = date; progress.date = date;
progress.changed = false; progress.changed = false;
// check intergiry with max allowed counter value
if (uint32 maxcounter = GetCriteriaProgressMaxCounter(criteria))
{
if (progress.counter > maxcounter)
{
progress.counter = maxcounter;
progress.changed = true;
}
}
} while(criteriaResult->NextRow()); } while(criteriaResult->NextRow());
delete criteriaResult; delete criteriaResult;
} }
@ -725,7 +735,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// init values, real set in switch // init values, real set in switch
uint32 change = 0; uint32 change = 0;
ProgressType progressType = PROGRESS_SET; ProgressType progressType = PROGRESS_HIGHEST; // when need it will replaced by PROGRESS_ACCUMULATE
switch (type) switch (type)
{ {
@ -876,7 +886,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue; continue;
change = GetPlayer()->getLevel(); change = GetPlayer()->getLevel();
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
@ -903,7 +913,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue; continue;
change = 1; change = 1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
@ -913,7 +923,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if(itr->second.m_rewarded) if(itr->second.m_rewarded)
counter++; counter++;
change = counter; change = counter;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
@ -930,7 +940,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
counter++; counter++;
} }
change = counter; change = counter;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
@ -1061,7 +1071,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// miscvalue1 is the ingame fallheight*100 as stored in dbc // miscvalue1 is the ingame fallheight*100 as stored in dbc
change = miscvalue1; change = miscvalue1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
@ -1110,7 +1120,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
change = 1; change = 1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
@ -1157,7 +1167,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue; continue;
change = 1; change = 1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
{ {
@ -1186,7 +1196,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if(miscvalue1 && achievementCriteria->own_item.itemID != miscvalue1) if(miscvalue1 && achievementCriteria->own_item.itemID != miscvalue1)
continue; continue;
change = GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true); change = GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true);
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
// miscvalue1 contains the personal rating // miscvalue1 contains the personal rating
@ -1201,7 +1211,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if(!data || !data->Meets(GetPlayer(),unit,miscvalue1)) if(!data || !data->Meets(GetPlayer(),unit,miscvalue1))
{ {
// reset the progress as we have a win without the requirement. // reset the progress as we have a win without the requirement.
SetCriteriaProgress(achievementCriteria, achievement, 0); SetCriteriaProgress(achievementCriteria, achievement, 0, PROGRESS_SET);
continue; continue;
} }
} }
@ -1258,12 +1268,12 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue; continue;
change = 1; change = 1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
change = GetPlayer()->GetBankBagSlotCount(); change = GetPlayer()->GetBankBagSlotCount();
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
{ {
@ -1272,17 +1282,17 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue; continue;
int32 reputation = GetPlayer()->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID); int32 reputation = GetPlayer()->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID);
if (!reputation) if (reputation <= 0)
continue; continue;
change = reputation; change = reputation;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
{ {
change = GetPlayer()->GetReputationMgr().GetExaltedFactionCount(); change = GetPlayer()->GetReputationMgr().GetExaltedFactionCount();
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
@ -1291,7 +1301,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if(!miscvalue1) if(!miscvalue1)
continue; continue;
change = 1; change = 1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
@ -1307,7 +1317,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if(!data || !data->Meets(GetPlayer(),unit,item_slot)) if(!data || !data->Meets(GetPlayer(),unit,item_slot))
continue; continue;
change = 1; change = 1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
@ -1378,7 +1388,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue; continue;
change = 1; change = 1;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
// miscvalue1 = go entry // miscvalue1 = go entry
@ -1435,7 +1445,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
} }
} }
change = spellCount; change = spellCount;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
@ -1459,15 +1469,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
change = GetPlayer()->GetReputationMgr().GetReveredFactionCount(); change = GetPlayer()->GetReputationMgr().GetReveredFactionCount();
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION: case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
change = GetPlayer()->GetReputationMgr().GetHonoredFactionCount(); change = GetPlayer()->GetReputationMgr().GetHonoredFactionCount();
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS: case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
change = GetPlayer()->GetReputationMgr().GetVisibleFactionCount(); change = GetPlayer()->GetReputationMgr().GetVisibleFactionCount();
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
@ -1498,12 +1508,12 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
spellCount++; spellCount++;
} }
change = spellCount; change = spellCount;
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL: case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
change = GetPlayer()->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS); change = GetPlayer()->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS);
progressType = PROGRESS_SET; progressType = PROGRESS_HIGHEST;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
if (!miscvalue1 || miscvalue1 != achievementCriteria->hk_class.classID) if (!miscvalue1 || miscvalue1 != achievementCriteria->hk_class.classID)

View file

@ -273,8 +273,9 @@ class AchievementMgr
static uint32 GetCriteriaProgressMaxCounter(AchievementCriteriaEntry const* entry); static uint32 GetCriteriaProgressMaxCounter(AchievementCriteriaEntry const* entry);
// Use PROGRESS_SET only for reset/downgrade criteria progress
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST }; enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST };
void SetCriteriaProgress(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint32 changeValue, ProgressType ptype = PROGRESS_SET); void SetCriteriaProgress(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint32 changeValue, ProgressType ptype);
private: private:
void SendAchievementEarned(AchievementEntry const* achievement); void SendAchievementEarned(AchievementEntry const* achievement);

View file

@ -1117,7 +1117,7 @@ bool ChatHandler::HandleAchievementAddCommand(char* args)
continue; continue;
uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(*itr); uint32 maxValue = AchievementMgr::GetCriteriaProgressMaxCounter(*itr);
mgr.SetCriteriaProgress(*itr, achEntry, maxValue); mgr.SetCriteriaProgress(*itr, achEntry, maxValue, AchievementMgr::PROGRESS_SET);
} }
} }
@ -1151,7 +1151,7 @@ bool ChatHandler::HandleAchievementRemoveCommand(char* args)
if (AchievementCriteriaEntryList const* criteriaList = sAchievementMgr.GetAchievementCriteriaByAchievement(achEntry->ID)) if (AchievementCriteriaEntryList const* criteriaList = sAchievementMgr.GetAchievementCriteriaByAchievement(achEntry->ID))
for (AchievementCriteriaEntryList::const_iterator itr = criteriaList->begin(); itr != criteriaList->end(); ++itr) for (AchievementCriteriaEntryList::const_iterator itr = criteriaList->begin(); itr != criteriaList->end(); ++itr)
mgr.SetCriteriaProgress(*itr, achEntry, 0); mgr.SetCriteriaProgress(*itr, achEntry, 0, AchievementMgr::PROGRESS_SET);
LocaleConstant loc = GetSessionDbcLocale(); LocaleConstant loc = GetSessionDbcLocale();
CompletedAchievementData const* completed = target ? target->GetAchievementMgr().GetCompleteData(achId) : NULL; CompletedAchievementData const* completed = target ? target->GetAchievementMgr().GetCompleteData(achId) : NULL;
@ -1218,7 +1218,7 @@ bool ChatHandler::HandleAchievementCriteriaAddCommand(char* args)
new_val = progress < max_int && max_int - progress > val ? progress + val : max_int; new_val = progress < max_int && max_int - progress > val ? progress + val : max_int;
} }
mgr.SetCriteriaProgress(criEntry, achEntry, new_val); // value will move to allowed range into function mgr.SetCriteriaProgress(criEntry, achEntry, new_val, AchievementMgr::PROGRESS_SET);
ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target); ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target);
return true; return true;
@ -1275,7 +1275,7 @@ bool ChatHandler::HandleAchievementCriteriaRemoveCommand(char* args)
uint32 newval = change < progress ? progress - change : 0; uint32 newval = change < progress ? progress - change : 0;
mgr.SetCriteriaProgress(criEntry, achEntry, newval); // value will move to allowed range into function mgr.SetCriteriaProgress(criEntry, achEntry, newval, AchievementMgr::PROGRESS_SET);
ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target); ShowAchievementCriteriaListHelper(criEntry, achEntry, loc, target);
return true; return true;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10346" #define REVISION_NR "10347"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__