mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-24 07:30:07 -04:00
Core/Achievements: Greatly optimize achievement system by splitting large types by miscvalue
Closes #18633
This commit is contained in:
@@ -482,7 +482,7 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
|
||||
if (m_player->IsGameMaster())
|
||||
return;
|
||||
|
||||
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
|
||||
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, 0/*get all*/);
|
||||
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
|
||||
{
|
||||
AchievementCriteriaEntry const* achievementCriteria = (*i);
|
||||
@@ -741,7 +741,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
TC_LOG_DEBUG("achievement", "UpdateAchievementCriteria: %s, %s (%u), %u, %u"
|
||||
, m_player->GetGUID().ToString().c_str(), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2);
|
||||
|
||||
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
|
||||
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, miscValue1);
|
||||
for (AchievementCriteriaEntry const* achievementCriteria : achievementCriteriaList)
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->ReferredAchievement);
|
||||
@@ -768,7 +768,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
switch (type)
|
||||
{
|
||||
// std. case: increment at 1
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
|
||||
@@ -808,9 +810,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
// std case: increment at miscvalue1
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
|
||||
@@ -864,7 +864,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
SetCriteriaProgress(achievementCriteria, maxSkillvalue);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
|
||||
if (m_completedAchievements.find(achievementCriteria->Asset.AchievementID) != m_completedAchievements.end())
|
||||
if ((miscValue1 && achievementCriteria->Asset.AchievementID == miscValue1) || (!miscValue1 && m_completedAchievements.find(achievementCriteria->Asset.AchievementID) != m_completedAchievements.end()))
|
||||
SetCriteriaProgress(achievementCriteria, 1);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
|
||||
@@ -1492,7 +1492,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
||||
|
||||
sAchievementMgr->SetRealmCompleted(achievement, GetPlayer()->GetInstanceId());
|
||||
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, achievement->ID);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->Points);
|
||||
|
||||
// reward items and titles if any
|
||||
@@ -1879,11 +1879,11 @@ bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const* achie
|
||||
return false;
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
|
||||
// miscvalue1 = itemid
|
||||
// miscvalue2 = itemSlot
|
||||
if (!miscValue1)
|
||||
// miscvalue1 = itemSlot
|
||||
// miscvalue2 = itemid
|
||||
if (!miscValue2)
|
||||
return false;
|
||||
if (miscValue2 != achievementCriteria->Asset.ItemSlot)
|
||||
if (miscValue1 != achievementCriteria->Asset.ItemSlot)
|
||||
return false;
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
|
||||
@@ -2187,6 +2187,60 @@ AchievementGlobalMgr* AchievementGlobalMgr::instance()
|
||||
return &instance;
|
||||
}
|
||||
|
||||
inline bool IsAchievementCriteriaTypeStoredByMiscValue(AchievementCriteriaTypes type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type, uint32 miscValue) const
|
||||
{
|
||||
if (miscValue && IsAchievementCriteriaTypeStoredByMiscValue(type))
|
||||
{
|
||||
auto itr = m_AchievementCriteriasByMiscValue[type].find(miscValue);
|
||||
if (itr != m_AchievementCriteriasByMiscValue[type].end())
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
return m_AchievementCriteriasByType[type];
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
||||
{
|
||||
@@ -2205,11 +2259,42 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
||||
if (!criteria)
|
||||
continue;
|
||||
|
||||
ASSERT(criteria->Type < ACHIEVEMENT_CRITERIA_TYPE_TOTAL, "ACHIEVEMENT_CRITERIA_TYPE_TOTAL must be greater than or equal to %u but is currently equal to %u",
|
||||
criteria->Type + 1, ACHIEVEMENT_CRITERIA_TYPE_TOTAL);
|
||||
|
||||
m_AchievementCriteriasByType[criteria->Type].push_back(criteria);
|
||||
m_AchievementCriteriaListByAchievement[criteria->ReferredAchievement].push_back(criteria);
|
||||
if (IsAchievementCriteriaTypeStoredByMiscValue(AchievementCriteriaTypes(criteria->Type)))
|
||||
{
|
||||
if (criteria->Type != ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA)
|
||||
m_AchievementCriteriasByMiscValue[criteria->Type][criteria->Asset.ID].push_back(criteria);
|
||||
else
|
||||
{
|
||||
WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(criteria->Asset.WorldMapOverlayID);
|
||||
if (!worldOverlayEntry)
|
||||
break;
|
||||
|
||||
for (uint8 j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j)
|
||||
{
|
||||
if (worldOverlayEntry->areatableID[j])
|
||||
{
|
||||
bool valid = true;
|
||||
for (uint8 i = 0; i < j; ++i)
|
||||
if (worldOverlayEntry->areatableID[j] == worldOverlayEntry->areatableID[i])
|
||||
valid = false;
|
||||
if (valid)
|
||||
m_AchievementCriteriasByMiscValue[criteria->Type][worldOverlayEntry->areatableID[j]].push_back(criteria);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (criteria->StartTimer)
|
||||
{
|
||||
ASSERT(criteria->StartEvent < ACHIEVEMENT_TIMED_TYPE_MAX, "ACHIEVEMENT_TIMED_TYPE_MAX must be greater than or equal to %u but is currently equal to %u",
|
||||
criteria->StartEvent + 1, ACHIEVEMENT_TIMED_TYPE_MAX);
|
||||
m_AchievementCriteriasByTimedType[criteria->StartEvent].push_back(criteria);
|
||||
}
|
||||
|
||||
++loaded;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef std::vector<AchievementCriteriaEntry const*> AchievementCriteriaEntryLis
|
||||
typedef std::vector<AchievementEntry const*> AchievementEntryList;
|
||||
|
||||
typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
|
||||
typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByMiscValue;
|
||||
typedef std::unordered_map<uint32, AchievementEntryList> AchievementListByReferencedId;
|
||||
|
||||
struct CriteriaProgress
|
||||
@@ -231,7 +232,7 @@ struct TC_GAME_API AchievementCriteriaDataSet
|
||||
Storage storage;
|
||||
};
|
||||
|
||||
typedef std::map<uint32, AchievementCriteriaDataSet> AchievementCriteriaDataMap;
|
||||
typedef std::unordered_map<uint32, AchievementCriteriaDataSet> AchievementCriteriaDataMap;
|
||||
|
||||
struct AchievementReward
|
||||
{
|
||||
@@ -324,10 +325,7 @@ class TC_GAME_API AchievementGlobalMgr
|
||||
|
||||
static AchievementGlobalMgr* instance();
|
||||
|
||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type) const
|
||||
{
|
||||
return m_AchievementCriteriasByType[type];
|
||||
}
|
||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type, uint32 miscValue) const;
|
||||
|
||||
AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type) const
|
||||
{
|
||||
@@ -401,6 +399,9 @@ class TC_GAME_API AchievementGlobalMgr
|
||||
// store achievement criterias by type to speed up lookup
|
||||
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
||||
|
||||
// store achievement criterias split by misc values
|
||||
AchievementCriteriaListByMiscValue m_AchievementCriteriasByMiscValue[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
||||
|
||||
AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX];
|
||||
|
||||
// store achievement criterias by achievement to speed up lookup
|
||||
|
||||
@@ -823,7 +823,7 @@ void Battleground::EndBattleground(uint32 winner)
|
||||
player->SetRandomWinner(true);
|
||||
}
|
||||
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1);
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, player->GetMapId());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -841,7 +841,7 @@ void Battleground::EndBattleground(uint32 winner)
|
||||
WorldPacket data;
|
||||
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam());
|
||||
player->SendDirectMessage(&data);
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, player->GetMapId());
|
||||
}
|
||||
|
||||
if (winmsg_id)
|
||||
|
||||
@@ -231,7 +231,7 @@ enum AchievementCriteriaTypes
|
||||
ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS = 119,
|
||||
};
|
||||
|
||||
#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 120
|
||||
#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 124
|
||||
|
||||
enum AchievementCategory
|
||||
{
|
||||
|
||||
@@ -6512,7 +6512,7 @@ void Player::CheckAreaExploreAndOutdoor()
|
||||
{
|
||||
SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
|
||||
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA, GetAreaId());
|
||||
|
||||
if (areaEntry->area_level > 0)
|
||||
{
|
||||
@@ -12108,7 +12108,7 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
|
||||
|
||||
// only for full equip instead adding to stack
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, slot, pItem->GetEntry());
|
||||
|
||||
return pItem;
|
||||
}
|
||||
@@ -12133,7 +12133,7 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem)
|
||||
CheckTitanGripPenalty();
|
||||
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, slot, pItem->GetEntry());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user