diff options
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.cpp | 85 | ||||
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 21 |
4 files changed, 84 insertions, 26 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 642c21e3ff1..0a8f9d95871 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -85,7 +85,7 @@ bool AchievementMgr::CanUpdateCriteriaTree(Criteria const* criteria, CriteriaTre return false; } - return true; + return CriteriaHandler::CanUpdateCriteriaTree(criteria, tree, referencePlayer); } bool AchievementMgr::CanCompleteCriteriaTree(CriteriaTree const* tree) diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index e8e418001ad..8f2dfcda625 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -936,37 +936,80 @@ bool CriteriaHandler::IsCompletedCriteriaTree(CriteriaTree const* tree) return false; uint64 requiredCount = tree->Entry->Amount; - uint64 completedCount = 0; - uint32 op = tree->Entry->Operator; - bool hasAll = true; - - // Check criteria we depend on first - for (CriteriaTree const* node : tree->Children) + switch (tree->Entry->Operator) { - if (IsCompletedCriteriaTree(node)) - ++completedCount; - else - hasAll = false; + case CRITERIA_TREE_OPERATOR_SINGLE: + return tree->Criteria && IsCompletedCriteria(tree->Criteria, requiredCount); + case CRITERIA_TREE_OPERATOR_SINGLE_NOT_COMPLETED: + return !tree->Criteria || !IsCompletedCriteria(tree->Criteria, requiredCount); + case CRITERIA_TREE_OPERATOR_ALL: + for (CriteriaTree const* node : tree->Children) + if (!IsCompletedCriteriaTree(node)) + return false; + return true; + case CRITERIA_TREE_OPERAROR_SUM_CHILDREN: + { + uint64 progress = 0; + CriteriaMgr::WalkCriteriaTree(tree, [this, &progress](CriteriaTree const* criteriaTree) + { + if (criteriaTree->Criteria) + if (CriteriaProgress const* criteriaProgress = GetCriteriaProgress(criteriaTree->Criteria)) + progress += criteriaProgress->Counter; + }); + return progress >= requiredCount; + } + case CRITERIA_TREE_OPERATOR_MAX_CHILD: + { + uint64 progress = 0; + CriteriaMgr::WalkCriteriaTree(tree, [this, &progress](CriteriaTree const* criteriaTree) + { + if (criteriaTree->Criteria) + if (CriteriaProgress const* criteriaProgress = GetCriteriaProgress(criteriaTree->Criteria)) + if (criteriaProgress->Counter > progress) + progress = criteriaProgress->Counter; + }); + return progress >= requiredCount; + } + case CRITERIA_TREE_OPERATOR_COUNT_DIRECT_CHILDREN: + { + uint64 progress = 0; + for (CriteriaTree const* node : tree->Children) + if (node->Criteria) + if (CriteriaProgress const* criteriaProgress = GetCriteriaProgress(node->Criteria)) + if (criteriaProgress->Counter >= 1) + if (++progress >= requiredCount) + return true; - if (op & CRITERIA_TREE_OPERATOR_ANY && completedCount >= requiredCount) + return false; + } + case CRITERIA_TREE_OPERATOR_ANY: { - if (!tree->Criteria) - return true; + uint64 progress = 0; + for (CriteriaTree const* node : tree->Children) + if (IsCompletedCriteriaTree(node)) + if (++progress >= requiredCount) + return true; - break; + return false; } + default: + break; } - if (op & CRITERIA_TREE_OPERATOR_ANY && completedCount < requiredCount) - return false; + return false; +} - if (op & CRITERIA_TREE_OPERATOR_ALL && !hasAll) +bool CriteriaHandler::CanUpdateCriteriaTree(Criteria const* criteria, CriteriaTree const* tree, Player* referencePlayer) const +{ + if ((tree->Entry->Flags & CRITERIA_TREE_FLAG_HORDE_ONLY && referencePlayer->GetTeam() != HORDE) || + (tree->Entry->Flags & CRITERIA_TREE_FLAG_ALLIANCE_ONLY && referencePlayer->GetTeam() != ALLIANCE)) + { + TC_LOG_TRACE("criteria", "CriteriaHandler::CanUpdateCriteriaTree: (Id: %u Type %s CriteriaTree %u) Wrong faction", + criteria->ID, CriteriaMgr::GetCriteriaTypeString(criteria->Entry->Type), tree->Entry->ID); return false; + } - if (!tree->Criteria) - return true; - - return IsCompletedCriteria(tree->Criteria, requiredCount); + return true; } bool CriteriaHandler::CanCompleteCriteriaTree(CriteriaTree const* /*tree*/) diff --git a/src/server/game/Achievements/CriteriaHandler.h b/src/server/game/Achievements/CriteriaHandler.h index 03a4f30136e..91bedbab44f 100644 --- a/src/server/game/Achievements/CriteriaHandler.h +++ b/src/server/game/Achievements/CriteriaHandler.h @@ -273,7 +273,7 @@ protected: virtual void SendCriteriaProgressRemoved(uint32 criteriaId) = 0; bool IsCompletedCriteriaTree(CriteriaTree const* tree); - virtual bool CanUpdateCriteriaTree(Criteria const* criteria, CriteriaTree const* tree, Player* referencePlayer) const = 0; + virtual bool CanUpdateCriteriaTree(Criteria const* criteria, CriteriaTree const* tree, Player* referencePlayer) const; virtual bool CanCompleteCriteriaTree(CriteriaTree const* tree); virtual void CompletedCriteriaTree(CriteriaTree const* tree, Player* referencePlayer) = 0; virtual void AfterCriteriaTreeUpdate(CriteriaTree const* /*tree*/, Player* /*referencePlayer*/) { } diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 710e92ca712..3501dbc55c9 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -407,10 +407,25 @@ enum CriteriaTypes #define CRITERIA_TYPE_TOTAL 190 -enum CriteriaTreeOperator +enum CriteriaTreeFlags : uint16 { - CRITERIA_TREE_OPERATOR_ALL = 4, - CRITERIA_TREE_OPERATOR_ANY = 8 + CRITERIA_TREE_FLAG_PROGRESS_BAR = 0x0001, + CRITERIA_TREE_FLAG_PROGRESS_IS_DATE = 0x0004, + CRITERIA_TREE_FLAG_SHOW_CURRENCY_ICON = 0x0008, + CRITERIA_TREE_FLAG_ALLIANCE_ONLY = 0x0200, + CRITERIA_TREE_FLAG_HORDE_ONLY = 0x0400, + CRITERIA_TREE_FLAG_SHOW_REQUIRED_COUNT = 0x0800 +}; + +enum CriteriaTreeOperator : uint8 +{ + CRITERIA_TREE_OPERATOR_SINGLE = 0, + CRITERIA_TREE_OPERATOR_SINGLE_NOT_COMPLETED = 1, + CRITERIA_TREE_OPERATOR_ALL = 4, + CRITERIA_TREE_OPERAROR_SUM_CHILDREN = 5, + CRITERIA_TREE_OPERATOR_MAX_CHILD = 6, + CRITERIA_TREE_OPERATOR_COUNT_DIRECT_CHILDREN = 7, + CRITERIA_TREE_OPERATOR_ANY = 8 }; enum Difficulty : uint8 |