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:
Shauren
2010-12-17 18:12:46 +01:00
parent 1cdeb4d057
commit b11e5bbf81
6 changed files with 94 additions and 21 deletions
+68 -10
View File
@@ -98,6 +98,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
break; break;
default: default:
sLog.outErrorDb("Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->requiredType); 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 false;
} }
return true; 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: 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); 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; 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()); ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId());
return false; return false;
} }
InstanceScript* data = ((InstanceMap*)map)->GetInstanceScript(); InstanceScript* instance = ((InstanceMap*)map)->GetInstanceScript();
if (!data) 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", 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()); ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId());
return false; 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: 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 false;
return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality; 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; return false;
} }
@@ -1446,8 +1459,12 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL: case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
{ {
// skip login update
if (!miscvalue1)
continue;
// those requirements couldn't be found in the dbc // those requirements couldn't be found in the dbc
AchievementCriteriaDataSet const* data = sAchievementMgr.GetCriteriaDataSet(achievementCriteria); AchievementCriteriaDataSet const* data = sAchievementMgr.GetCriteriaDataSet(achievementCriteria);
if (!data || !data->Meets(GetPlayer(), unit)) if (!data || !data->Meets(GetPlayer(), unit))
@@ -1456,6 +1473,42 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
break; 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 // std case: not exist in DBC, not triggered in code as result
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
@@ -1466,12 +1519,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break; break;
// FIXME: not triggered in code as result, need to implement // FIXME: not triggered in code as result, need to implement
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
case ACHIEVEMENT_CRITERIA_TYPE_PLAY_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_OWN_RANK:
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS: case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE: case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
@@ -1572,12 +1621,19 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->cast_spell.castCount; return progress->counter >= achievementCriteria->cast_spell.castCount;
case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
return progress->counter >= achievementCriteria->bg_objective.completeCount; 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: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
return progress->counter >= 1; 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: case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
return progress->counter >= achievementCriteria->own_item.itemCount; return progress->counter >= achievementCriteria->own_item.itemCount;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
return progress->counter >= achievementCriteria->win_rated_arena.count; 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: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
return progress->counter >= (achievementCriteria->learn_skill_level.skillLevel * 75); return progress->counter >= (achievementCriteria->learn_skill_level.skillLevel * 75);
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
@@ -1625,8 +1681,6 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->loot_type.lootTypeCount; return progress->counter >= achievementCriteria->loot_type.lootTypeCount;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
return progress->counter >= achievementCriteria->learn_skill_line.spellCount; 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: case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS:
return progress->counter >= 9000; return progress->counter >= 9000;
case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS: 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_CREATURE:
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS: case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS: case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS: 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_QUEST_ABANDONED:
case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
return false; default:
break;
} }
return false; return false;
} }
@@ -2228,6 +2284,8 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
break; // any cases break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL: case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
break; // any cases break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: // any cases
break;
default: // type not use DB data, ignore default: // type not use DB data, ignore
continue; 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_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_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_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 Player;
class Unit; class Unit;
@@ -162,6 +163,11 @@ struct AchievementCriteriaData
uint32 item_level; uint32 item_level;
uint32 item_quality; uint32 item_quality;
} equipped_item; } equipped_item;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20
struct
{
uint32 mapId;
} map_id;
// ... // ...
struct struct
{ {
@@ -663,7 +663,15 @@ void ArenaTeam::FinishGame(int32 mod)
if (int32(m_stats.rating) + mod < 0) if (int32(m_stats.rating) + mod < 0)
m_stats.rating = 0; m_stats.rating = 0;
else else
{
m_stats.rating += mod; 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_week += 1;
m_stats.games_season += 1; m_stats.games_season += 1;
-1
View File
@@ -134,7 +134,6 @@ enum AchievementCriteriaTypes
ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32, ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32,
ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33, ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33,
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34, 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_HONORABLE_KILL = 35,
ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36, ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36,
// TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc // 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_EARN_HONORABLE_KILL);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, pVictim->getClass()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, pVictim->getClass());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, pVictim->getRace()); 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 else
{ {
+1 -1
View File
@@ -668,7 +668,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
// call before auras are removed // call before auras are removed
if (Player* killer = this->ToPlayer()) // keep the this-> for clarity 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); Kill(pVictim, durabilityLoss);