aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Achievements/CriteriaHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Achievements/CriteriaHandler.cpp')
-rw-r--r--src/server/game/Achievements/CriteriaHandler.cpp85
1 files changed, 64 insertions, 21 deletions
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*/)