diff options
Diffstat (limited to 'src/game/AchievementMgr.cpp')
-rw-r--r-- | src/game/AchievementMgr.cpp | 109 |
1 files changed, 98 insertions, 11 deletions
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index e86fb543ed5..09ae58eea8d 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -35,6 +35,9 @@ #include "ProgressBar.h" #include "SpellMgr.h" +#include "MapManager.h" +#include "BattleGround.h" +#include "BattleGroundAB.h" INSTANTIATE_SINGLETON_1(AchievementGlobalMgr); @@ -81,11 +84,13 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) switch(criteria->requiredType) { case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // only hardcoded list + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // only hardcoded list case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: + case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: break; @@ -139,7 +144,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD: if (player_dead.own_team_flag > 1) { - sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong boolean value1 (%u).", + sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD (%u) have wrong boolean value1 (%u).", criteria->ID, criteria->requiredType,dataType,player_dead.own_team_flag); return false; } @@ -228,10 +233,12 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (!sHolidaysStore.LookupEntry(holiday.id)) { sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY (%u) have unknown holiday in value1 (%u), ignore.", - criteria->ID, criteria->requiredType,dataType,drunk.state); + criteria->ID, criteria->requiredType,dataType,holiday.id); return false; } return true; + case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE: + return true; // not check correctness node indexes default: sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) have data for not supported data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType); return false; @@ -300,6 +307,13 @@ bool AchievementCriteriaData::Meets(Player const* source, Unit const* target, ui return Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= drunk.state; case ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY: return IsHolidayActive(HolidayIds(holiday.id)); + case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE: + { + BattleGround* bg = source->GetBattleGround(); + if(!bg) + return false; + return bg->IsTeamScoreInRange(source->GetTeam()==ALLIANCE ? HORDE : ALLIANCE,bg_loss_team_score.min_score,bg_loss_team_score.max_score); + } } return false; } @@ -535,7 +549,7 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri if (!criteria) { // we will remove not existed criteria for all characters - sLog.outError("Not existed achievement creataria %u data removed from table `character_achievement_progress`.",id); + sLog.outError("Not existed achievement criteria %u data removed from table `character_achievement_progress`.",id); CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE criteria = %u",id); continue; } @@ -678,7 +692,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // std. case: increment at 1 case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS: - case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: @@ -719,6 +732,54 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // specialized cases + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + { + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if (!miscvalue1) + continue; + if (achievementCriteria->win_bg.bgMapID != GetPlayer()->GetMapId()) + continue; + + if (achievementCriteria->win_bg.additionalRequirement1_type) + { + // those requirements couldn't be found in the dbc + AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); + if (!data || !data->Meets(GetPlayer(),unit)) + continue; + } + // some hardcoded requirements + else + { + BattleGround* bg = GetPlayer()->GetBattleGround(); + if (!bg) + continue; + + switch(achievementCriteria->referredAchievement) + { + case 161: // AB, Overcome a 500 resource disadvantage + { + if (bg->GetTypeID() != BATTLEGROUND_AB) + continue; + if(!((BattleGroundAB*)bg)->IsTeamScores500disadvantage(GetPlayer()->GetTeam())) + continue; + break; + } + case 156: // AB, win while controlling all 5 flags (all nodes) + case 784: // EY, win while holding 4 bases (all nodes) + { + if(!bg->IsAllNodesConrolledByTeam(GetPlayer()->GetTeam())) + continue; + break; + } + case 1762: // SA, win without losing any siege vehicles + case 2192: // SA, win without losing any siege vehicles + continue; // not implemented + } + } + + SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE); + break; + } case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: { // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case @@ -827,8 +888,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(!miscvalue1) continue; - Map const* map = GetPlayer()->GetMap(); - if(!map->IsDungeon()) + Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : MapManager::Instance().FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); + if(!map || !map->IsDungeon()) continue; // search case @@ -1194,6 +1255,24 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui SetCriteriaProgress(achievementCriteria, spellCount); break; } + case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + + if(achievementCriteria->win_duel.duelCount) + { + // those requirements couldn't be found in the dbc + AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); + if(!data) + continue; + + if(!data->Meets(GetPlayer(),unit)) + continue; + } + + SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount()); break; @@ -1270,7 +1349,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_WIN_BG: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: @@ -1298,7 +1376,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(IsCompletedCriteria(achievementCriteria,achievement)) CompletedCriteriaFor(achievement); - // check again the completeness for SUMM and REQ COUNT achievements, + // check again the completeness for SUMM and REQ COUNT achievements, // as they don't depend on the completed criteria but on the sum of the progress of each individual criteria if (achievement->flags & ACHIEVEMENT_FLAG_SUMM) { @@ -1339,6 +1417,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve switch(achievementCriteria->requiredType) { + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + return progress->counter >= achievementCriteria->win_bg.winCount; case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: return progress->counter >= achievementCriteria->kill_creature.creatureCount; case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: @@ -1430,7 +1510,6 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return progress->counter >= achievementCriteria->learn_skill_line.spellCount; case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL: return progress->counter >= achievementCriteria->honorable_kill.killCount; - // handle all statistic-only criteria here case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: @@ -1514,7 +1593,7 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) return false; } - // Default case - need complete all or + // Default case - need complete all or bool completed_all = true; for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr) { @@ -1844,6 +1923,10 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() switch(criteria->requiredType) { + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + if(!criteria->win_bg.additionalRequirement1_type) + continue; + break; case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: break; // any cases case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: @@ -1878,6 +1961,10 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() if(criteria->do_emote.count==0) continue; break; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: // skip statistics + if(criteria->win_duel.duelCount==0) + continue; + break; case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: // any cases break; case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: // need skip generic cases |