aboutsummaryrefslogtreecommitdiff
path: root/src/game/AchievementMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/AchievementMgr.cpp')
-rw-r--r--src/game/AchievementMgr.cpp109
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