Core/Achievements: Prevent ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL updates at login
Core/Achievements: Implemented ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL Core/Achievements: Implemented ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA Core/Achievements: Implemented ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING Core/Achievements: Implemented ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING Core/Achievements: Implemented map id requirement for achievement criterias Closes issue #4479. Closes issue #4478. Closes issue #4473. Closes issue #4472. Closes issue #4471. Closes issue #4480. Closes issue #2284. Closes issue #4481. --HG-- branch : trunk
This commit is contained in:
@@ -98,6 +98,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorDb("Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->requiredType);
|
||||
@@ -260,6 +261,14 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
|
||||
if (!sMapStore.LookupEntry(map_id.mapId))
|
||||
{
|
||||
sLog.outErrorDb("Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.",
|
||||
criteria->ID, criteria->requiredType, dataType, map_id.mapId);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
sLog.outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType,dataType);
|
||||
return false;
|
||||
@@ -347,14 +356,14 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
|
||||
ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId());
|
||||
return false;
|
||||
}
|
||||
InstanceScript* data = ((InstanceMap*)map)->GetInstanceScript();
|
||||
if (!data)
|
||||
InstanceScript* instance = ((InstanceMap*)map)->GetInstanceScript();
|
||||
if (!instance)
|
||||
{
|
||||
sLog.outErrorDb("Achievement system call ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map does not have a instance script",
|
||||
ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId());
|
||||
return false;
|
||||
}
|
||||
return data->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);
|
||||
return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
|
||||
{
|
||||
@@ -363,6 +372,10 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
|
||||
return false;
|
||||
return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
|
||||
return source->GetMapId() == map_id.mapId;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1446,8 +1459,12 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
|
||||
{
|
||||
// skip login update
|
||||
if (!miscvalue1)
|
||||
continue;
|
||||
// those requirements couldn't be found in the dbc
|
||||
AchievementCriteriaDataSet const* data = sAchievementMgr.GetCriteriaDataSet(achievementCriteria);
|
||||
if (!data || !data->Meets(GetPlayer(), unit))
|
||||
@@ -1456,6 +1473,42 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
|
||||
{
|
||||
if (!miscvalue1 || miscvalue1 != achievementCriteria->honorable_kill_at_area.areaID)
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING:
|
||||
{
|
||||
uint32 reqTeamType = type == ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING ?
|
||||
achievementCriteria->highest_team_rating.teamtype :
|
||||
achievementCriteria->reach_team_rating.teamtype;
|
||||
|
||||
if (miscvalue1)
|
||||
{
|
||||
if (miscvalue2 != reqTeamType)
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_HIGHEST);
|
||||
}
|
||||
else // login case
|
||||
{
|
||||
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
|
||||
if (uint32 arena_team_id = GetPlayer()->GetArenaTeamId(arena_slot))
|
||||
if (ArenaTeam * at = sObjectMgr.GetArenaTeamById(arena_team_id))
|
||||
if (at->GetType() == reqTeamType)
|
||||
{
|
||||
SetCriteriaProgress(achievementCriteria, at->GetStats().rating, PROGRESS_HIGHEST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// std case: not exist in DBC, not triggered in code as result
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
|
||||
@@ -1466,12 +1519,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
break;
|
||||
// FIXME: not triggered in code as result, need to implement
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
|
||||
@@ -1572,12 +1621,19 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||
return progress->counter >= achievementCriteria->cast_spell.castCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
|
||||
return progress->counter >= achievementCriteria->bg_objective.completeCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
|
||||
return progress->counter >= achievementCriteria->honorable_kill_at_area.killCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
|
||||
return progress->counter >= 1;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
|
||||
return progress->counter >= achievementCriteria->honorable_kill.killCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
|
||||
return progress->counter >= achievementCriteria->own_item.itemCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
|
||||
return progress->counter >= achievementCriteria->win_rated_arena.count;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING:
|
||||
return progress->counter >= achievementCriteria->reach_team_rating.teamrating;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
|
||||
return progress->counter >= (achievementCriteria->learn_skill_level.skillLevel * 75);
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
|
||||
@@ -1625,8 +1681,6 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||
return progress->counter >= achievementCriteria->loot_type.lootTypeCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
|
||||
return progress->counter >= achievementCriteria->learn_skill_line.spellCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
|
||||
return progress->counter >= achievementCriteria->honorable_kill.killCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS:
|
||||
return progress->counter >= 9000;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
|
||||
@@ -1639,6 +1693,7 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
|
||||
@@ -1664,7 +1719,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2228,6 +2284,8 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
|
||||
break; // any cases
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
|
||||
break; // any cases
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: // any cases
|
||||
break;
|
||||
default: // type not use DB data, ignore
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -62,9 +62,10 @@ enum AchievementCriteriaDataType
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17,// min_score max_score player's team win bg and opposition team have team score in range
|
||||
ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18,// 0 0 maker instance script call for check current criteria requirements fit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19,// item_level item_quality for equipped item in slot to check item level and quality
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20,// map_id 0 player must be on map with id in map_id
|
||||
};
|
||||
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 20 // maximum value in AchievementCriteriaDataType enum
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 21 // maximum value in AchievementCriteriaDataType enum
|
||||
|
||||
class Player;
|
||||
class Unit;
|
||||
@@ -162,6 +163,11 @@ struct AchievementCriteriaData
|
||||
uint32 item_level;
|
||||
uint32 item_quality;
|
||||
} equipped_item;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20
|
||||
struct
|
||||
{
|
||||
uint32 mapId;
|
||||
} map_id;
|
||||
// ...
|
||||
struct
|
||||
{
|
||||
|
||||
@@ -663,7 +663,15 @@ void ArenaTeam::FinishGame(int32 mod)
|
||||
if (int32(m_stats.rating) + mod < 0)
|
||||
m_stats.rating = 0;
|
||||
else
|
||||
{
|
||||
m_stats.rating += mod;
|
||||
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
|
||||
if (Player* member = ObjectAccessor::FindPlayer(itr->guid))
|
||||
{
|
||||
member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING, m_stats.rating, m_Type);
|
||||
member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING, m_stats.rating, m_Type);
|
||||
}
|
||||
}
|
||||
|
||||
m_stats.games_week += 1;
|
||||
m_stats.games_season += 1;
|
||||
|
||||
@@ -134,7 +134,6 @@ enum AchievementCriteriaTypes
|
||||
ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34,
|
||||
// TODO: this criteria has additional conditions which can not be found in the dbcs
|
||||
ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35,
|
||||
ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36,
|
||||
// TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc
|
||||
|
||||
@@ -6887,6 +6887,8 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, int32 honor, bool pvpt
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, pVictim->getClass());
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, pVictim->getRace());
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId());
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, pVictim);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -668,7 +668,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
||||
|
||||
// call before auras are removed
|
||||
if (Player* killer = this->ToPlayer()) // keep the this-> for clarity
|
||||
killer->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 0, 0, pVictim);
|
||||
killer->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, pVictim);
|
||||
}
|
||||
|
||||
Kill(pVictim, durabilityLoss);
|
||||
|
||||
Reference in New Issue
Block a user