From 6f7ff9a3efd10cd4f776a67540109e7bb774f1c5 Mon Sep 17 00:00:00 2001 From: Xinef Date: Sun, 5 Feb 2017 16:39:56 +0100 Subject: Core/Achievements: Optimized resetting achievement criteria by condition and changed the functionality to properly reset all possible criteria with given condition Closes #18905 (cherry picked from commit 7c7b877c3fc0292f33f54f4e8b514be3bf8514a6) --- src/server/game/Achievements/AchievementMgr.cpp | 35 +++++++++++----------- src/server/game/Achievements/AchievementMgr.h | 2 +- src/server/game/Achievements/CriteriaHandler.cpp | 7 +++++ src/server/game/Achievements/CriteriaHandler.h | 7 +++++ src/server/game/Battlegrounds/Arena.cpp | 2 +- src/server/game/Battlegrounds/Battleground.cpp | 16 ++++------ src/server/game/DataStores/DBCEnums.h | 10 +++++-- src/server/game/Entities/Player/Player.cpp | 12 ++++---- src/server/game/Entities/Player/Player.h | 2 +- .../game/Quests/QuestObjectiveCriteriaMgr.cpp | 35 +++++++++++----------- src/server/game/Quests/QuestObjectiveCriteriaMgr.h | 2 +- .../Ulduar/Ulduar/boss_algalon_the_observer.cpp | 2 +- 12 files changed, 71 insertions(+), 61 deletions(-) diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 12e33cf9ee3..0f33174f40c 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -341,36 +341,35 @@ void PlayerAchievementMgr::SaveToDB(CharacterDatabaseTransaction& trans) } } -void PlayerAchievementMgr::ResetCriteria(CriteriaTypes type, uint64 miscValue1, uint64 miscValue2, bool evenIfCriteriaComplete) +void PlayerAchievementMgr::ResetCriteria(CriteriaCondition condition, int32 failAsset, bool evenIfCriteriaComplete) { - TC_LOG_DEBUG("criteria.achievement", "PlayerAchievementMgr::ResetCriteria(%u, " UI64FMTD ", " UI64FMTD ")", type, miscValue1, miscValue2); + TC_LOG_DEBUG("criteria.achievement", "PlayerAchievementMgr::ResetCriteria(%u, %d, %s)", condition, failAsset, evenIfCriteriaComplete ? "true" : "false"); // disable for gamemasters with GM-mode enabled if (_owner->IsGameMaster()) return; - CriteriaList const& achievementCriteriaList = GetCriteriaByType(type); - for (Criteria const* achievementCriteria : achievementCriteriaList) + if (CriteriaList const* achievementCriteriaList = sCriteriaMgr->GetCriteriaByFailEvent(condition, failAsset)) { - if (achievementCriteria->Entry->FailEvent != miscValue1 || (achievementCriteria->Entry->FailAsset && achievementCriteria->Entry->FailAsset != int64(miscValue2))) - continue; - - std::vector const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(achievementCriteria->ID); - bool allComplete = true; - for (CriteriaTree const* tree : *trees) + for (Criteria const* achievementCriteria : *achievementCriteriaList) { - // don't update already completed criteria if not forced or achievement already complete - if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete) || !HasAchieved(tree->Achievement->ID)) + std::vector const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(achievementCriteria->ID); + bool allComplete = true; + for (CriteriaTree const* tree : *trees) { - allComplete = false; - break; + // don't update already completed criteria if not forced or achievement already complete + if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete) || !HasAchieved(tree->Achievement->ID)) + { + allComplete = false; + break; + } } - } - if (allComplete) - continue; + if (allComplete) + continue; - RemoveCriteriaProgress(achievementCriteria); + RemoveCriteriaProgress(achievementCriteria); + } } } diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index b8f314d5b43..966b990ce3e 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -83,7 +83,7 @@ public: void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult); void SaveToDB(CharacterDatabaseTransaction& trans); - void ResetCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false); + void ResetCriteria(CriteriaCondition condition, int32 failAsset, bool evenIfCriteriaComplete = false); void SendAllData(Player const* receiver) const override; void SendAchievementInfo(Player* receiver, uint32 achievementId = 0) const; diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index 288be7eea6f..92b5c88d291 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -3270,6 +3270,10 @@ void CriteriaMgr::LoadCriteriaList() { ASSERT(criteriaEntry->Type < CRITERIA_TYPE_TOTAL, "CRITERIA_TYPE_TOTAL must be greater than or equal to %u but is currently equal to %u", criteriaEntry->Type + 1, CRITERIA_TYPE_TOTAL); + ASSERT(criteriaEntry->StartEvent < CRITERIA_TIMED_TYPE_MAX, "CRITERIA_TYPE_TOTAL must be greater than or equal to %u but is currently equal to %u", + criteriaEntry->StartEvent + 1, CRITERIA_TIMED_TYPE_MAX); + ASSERT(criteriaEntry->FailEvent < CRITERIA_CONDITION_MAX, "CRITERIA_CONDITION_MAX must be greater than or equal to %u but is currently equal to %u", + criteriaEntry->FailEvent + 1, CRITERIA_CONDITION_MAX); auto treeItr = _criteriaTreeByCriteria.find(criteriaEntry->ID); if (treeItr == _criteriaTreeByCriteria.end()) @@ -3327,6 +3331,9 @@ void CriteriaMgr::LoadCriteriaList() if (criteriaEntry->StartTimer) _criteriasByTimedType[criteriaEntry->StartEvent].push_back(criteria); + + if (criteriaEntry->FailEvent) + _criteriasByFailEvent[criteriaEntry->FailEvent][criteriaEntry->FailAsset].push_back(criteria); } for (auto& p : _criteriaTrees) diff --git a/src/server/game/Achievements/CriteriaHandler.h b/src/server/game/Achievements/CriteriaHandler.h index 51415c36212..56b8b977a03 100644 --- a/src/server/game/Achievements/CriteriaHandler.h +++ b/src/server/game/Achievements/CriteriaHandler.h @@ -351,6 +351,12 @@ public: return _criteriasByTimedType[type]; } + CriteriaList const* GetCriteriaByFailEvent(CriteriaCondition condition, int32 asset) + { + auto itr = _criteriasByFailEvent[condition].find(asset); + return itr != _criteriasByFailEvent[condition].end() ? &itr->second : nullptr; + } + CriteriaDataSet const* GetCriteriaDataSet(Criteria const* Criteria) const { CriteriaDataMap::const_iterator iter = _criteriaDataMap.find(Criteria->ID); @@ -407,6 +413,7 @@ private: CriteriaList _questObjectiveCriteriasByType[CRITERIA_TYPE_TOTAL]; CriteriaList _criteriasByTimedType[CRITERIA_TIMED_TYPE_MAX]; + std::unordered_map _criteriasByFailEvent[CRITERIA_CONDITION_MAX]; }; #define sCriteriaMgr CriteriaMgr::Instance() diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index 129c0df6ce1..c642fdc1b62 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -274,7 +274,7 @@ void Arena::EndBattleground(uint32 winner) loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); // Arena lost => reset the win_rated_arena having the "no_lose" condition - player->ResetCriteria(CRITERIA_TYPE_WIN_RATED_ARENA, CRITERIA_CONDITION_NO_LOSE); + player->ResetCriteria(CRITERIA_CONDITION_NO_LOSE, 0); } } diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 7b5972cf394..cd9303828a4 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -973,6 +973,9 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen // reset destination bg team player->SetBGTeam(0); + // remove all criterias on bg leave + player->ResetCriteria(CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + if (Transport) player->TeleportToBGEntryPoint(); @@ -1093,17 +1096,8 @@ void Battleground::AddPlayer(Player* player) } } - player->ResetCriteria(CRITERIA_TYPE_KILL_CREATURE, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_WIN_BG, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_DAMAGE_DONE, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_BE_SPELL_TARGET, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_CAST_SPELL, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_HONORABLE_KILL, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_HEALING_DONE, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_GET_KILLING_BLOWS, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->ResetCriteria(CRITERIA_TYPE_SPECIAL_PVP_KILL, CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + // reset all map criterias on map enter + player->ResetCriteria(CRITERIA_CONDITION_BG_MAP, GetMapId(), true); // setup BG group membership PlayerAddedToBGCheckIfBGIsRunning(player); diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index ce41455e934..65e0134a964 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -213,11 +213,15 @@ enum CriteriaCondition CRITERIA_CONDITION_UNK2 = 2, // only used in "Complete a daily quest every day for five consecutive days" CRITERIA_CONDITION_BG_MAP = 3, // requires you to be on specific map, reset at change CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing" - CRITERIA_CONDITION_UNK5 = 5, // Have spell? - CRITERIA_CONDITION_UNK8 = 8, + CRITERIA_CONDITION_REMOVE_AURA = 5, // reset when this aura is removed + CRITERIA_CONDITION_CAST_SPELL = 8, // reset when casting this spell CRITERIA_CONDITION_NO_SPELL_HIT = 9, // requires the player not to be hit by specific spell CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group - CRITERIA_CONDITION_UNK13 = 13 // unk + CRITERIA_CONDITION_LOSE_PET_BATTLE = 11, // reset when losing pet battle + CRITERIA_CONDITION_UNK13 = 13, // unk + CRITERIA_CONDITION_EVENT = 14, + + CRITERIA_CONDITION_MAX }; enum CriteriaAdditionalCondition diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index dc29174025a..b932d9e35c4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1372,9 +1372,9 @@ void Player::setDeathState(DeathState s) UpdateCriteria(CRITERIA_TYPE_DEATH_AT_MAP, 1); UpdateCriteria(CRITERIA_TYPE_DEATH, 1); UpdateCriteria(CRITERIA_TYPE_DEATH_IN_DUNGEON, 1); - ResetCriteria(CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, CRITERIA_CONDITION_NO_DEATH); - ResetCriteria(CRITERIA_TYPE_HONORABLE_KILL, CRITERIA_CONDITION_NO_DEATH); - ResetCriteria(CRITERIA_TYPE_GET_KILLING_BLOWS, CRITERIA_CONDITION_NO_DEATH); + + // reset all death criterias + ResetCriteria(CRITERIA_CONDITION_NO_DEATH, 0); } Unit::setDeathState(s); @@ -26492,10 +26492,10 @@ void Player::RemoveCriteriaTimer(CriteriaTimedTypes type, uint32 entry) m_achievementMgr->RemoveCriteriaTimer(type, entry); } -void Player::ResetCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/) +void Player::ResetCriteria(CriteriaCondition condition, int32 failAsset, bool evenIfCriteriaComplete /* = false*/) { - m_achievementMgr->ResetCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); - m_questObjectiveCriteriaMgr->ResetCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); + m_achievementMgr->ResetCriteria(condition, failAsset, evenIfCriteriaComplete); + m_questObjectiveCriteriaMgr->ResetCriteria(condition, failAsset, evenIfCriteriaComplete); } void Player::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit* unit /*= NULL*/) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index acbc5dd6086..0eacdb13fe1 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2320,7 +2320,7 @@ class TC_GAME_API Player : public Unit, public GridObject uint32 GetAchievementPoints() const; bool HasAchieved(uint32 achievementId) const; void ResetAchievements(); - void ResetCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false); + void ResetCriteria(CriteriaCondition condition, int32 failAsset, bool evenIfCriteriaComplete = false); void UpdateCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit* unit = NULL); void StartCriteriaTimer(CriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0); void RemoveCriteriaTimer(CriteriaTimedTypes type, uint32 entry); diff --git a/src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp b/src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp index f804ad52e94..8486db1c166 100644 --- a/src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp +++ b/src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp @@ -161,36 +161,35 @@ void QuestObjectiveCriteriaMgr::SaveToDB(CharacterDatabaseTransaction& trans) } } -void QuestObjectiveCriteriaMgr::ResetCriteria(CriteriaTypes type, uint64 miscValue1, uint64 miscValue2, bool evenIfCriteriaComplete) +void QuestObjectiveCriteriaMgr::ResetCriteria(CriteriaCondition condition, int32 failAsset, bool evenIfCriteriaComplete) { - TC_LOG_DEBUG("criteria.quest", "QuestObjectiveCriteriaMgr::ResetCriteria(%u, " UI64FMTD ", " UI64FMTD ")", type, miscValue1, miscValue2); + TC_LOG_DEBUG("criteria.quest", "QuestObjectiveCriteriaMgr::ResetCriteria(%u, %d, %s)", condition, failAsset, evenIfCriteriaComplete ? "true" : "false"); // disable for gamemasters with GM-mode enabled if (_owner->IsGameMaster()) return; - CriteriaList const& playerCriteriaList = GetCriteriaByType(type); - for (Criteria const* playerCriteria : playerCriteriaList) + if (CriteriaList const* playerCriteriaList = sCriteriaMgr->GetCriteriaByFailEvent(condition, failAsset)) { - if (playerCriteria->Entry->FailEvent != miscValue1 || (playerCriteria->Entry->FailAsset && playerCriteria->Entry->FailAsset != int64(miscValue2))) - continue; - - std::vector const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(playerCriteria->ID); - bool allComplete = true; - for (CriteriaTree const* tree : *trees) + for (Criteria const* playerCriteria : *playerCriteriaList) { - // don't update already completed criteria if not forced - if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete)) + std::vector const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(playerCriteria->ID); + bool allComplete = true; + for (CriteriaTree const* tree : *trees) { - allComplete = false; - break; + // don't update already completed criteria if not forced + if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete)) + { + allComplete = false; + break; + } } - } - if (allComplete) - continue; + if (allComplete) + continue; - RemoveCriteriaProgress(playerCriteria); + RemoveCriteriaProgress(playerCriteria); + } } } diff --git a/src/server/game/Quests/QuestObjectiveCriteriaMgr.h b/src/server/game/Quests/QuestObjectiveCriteriaMgr.h index 290e1838e33..44748b27ba2 100644 --- a/src/server/game/Quests/QuestObjectiveCriteriaMgr.h +++ b/src/server/game/Quests/QuestObjectiveCriteriaMgr.h @@ -34,7 +34,7 @@ public: void LoadFromDB(PreparedQueryResult objectiveResult, PreparedQueryResult criteriaResult); void SaveToDB(CharacterDatabaseTransaction& trans); - void ResetCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false); + void ResetCriteria(CriteriaCondition condition, int32 failAsset, bool evenIfCriteriaComplete = false); void ResetCriteriaTree(uint32 criteriaTreeId); void SendAllData(Player const* receiver) const override; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 4e5019618ec..1884efd8916 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -1358,7 +1358,7 @@ class spell_algalon_supermassive_fail : public SpellScriptLoader if (!GetHitPlayer()) return; - GetHitPlayer()->ResetCriteria(CRITERIA_TYPE_BE_SPELL_TARGET, CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true); + GetHitPlayer()->ResetCriteria(CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true); } void Register() override -- cgit v1.2.3