Пример #1
0
        /**
         * 添加TagToAdd到container, 但会删除gameplaytags列表中TagToAdd相关的parent tag
         * 如果TagToAdd已经在gameplaytags列表中, 就不会被添加
         */
        public bool AddLeafTag(CGameplayTag TagToAdd)
        {
            // Check tag is not already explicitly in container
            if (HasTagExact(TagToAdd))
            {
                return(true);
            }

            // If this tag is parent of explicitly added tag, fail
            if (HasTag(TagToAdd))
            {
                return(false);
            }

            CGameplayTagContainer tagToAddContainer = CGameplayTagsManager.Instance.GetSingleTagContainer(TagToAdd);

            if (tagToAddContainer == null)
            {
                return(false);
            }

            // Remove any tags in the container that are a parent to TagToAdd
            foreach (CGameplayTag ParentTag in tagToAddContainer.ParentTags)
            {
                if (HasTagExact(ParentTag))
                {
                    RemoveTag(ParentTag);
                }
            }

            // Add the tag
            AddTag(TagToAdd);
            return(true);
        }
Пример #2
0
        private bool EvalNoExprMatch(CGameplayTagContainer Tags, bool bSkip)
        {
            bool bShortCircuit = bSkip;

            // assume true until proven otherwise
            bool Result = true;

            // parse exprset
            byte NumExprs = GetToken();

            if (bReadError)
            {
                return(false);
            }

            for (byte Idx = 0; Idx < NumExprs; ++Idx)
            {
                bool bExprResult = EvalExpr(Tags, bShortCircuit);
                if (bShortCircuit == false)
                {
                    if (bExprResult == true)
                    {
                        // one match is sufficient for fail result
                        Result        = false;
                        bShortCircuit = true;
                    }
                }
            }

            return(Result);
        }
Пример #3
0
        private bool EvalExpr(CGameplayTagContainer Tags, bool bSkip = false)
        {
            CGameplayTagQueryExprType ExprType = (CGameplayTagQueryExprType)GetToken();

            if (bReadError)
            {
                return(false);
            }

            switch (ExprType)
            {
            case CGameplayTagQueryExprType.AnyTagsMatch:
                return(EvalAnyTagsMatch(Tags, bSkip));

            case CGameplayTagQueryExprType.AllTagsMatch:
                return(EvalAllTagsMatch(Tags, bSkip));

            case CGameplayTagQueryExprType.NoTagsMatch:
                return(EvalNoTagsMatch(Tags, bSkip));

            case CGameplayTagQueryExprType.AnyExprMatch:
                return(EvalAnyExprMatch(Tags, bSkip));

            case CGameplayTagQueryExprType.AllExprMatch:
                return(EvalAllExprMatch(Tags, bSkip));

            case CGameplayTagQueryExprType.NoExprMatch:
                return(EvalNoExprMatch(Tags, bSkip));
            }

            return(false);
        }
Пример #4
0
        /// <summary>
        /// 根据传入的tag列表, 创建container
        /// </summary>
        public static CGameplayTagContainer CreateFromArray(List <CGameplayTag> SourceTags)
        {
            CGameplayTagContainer container = new CGameplayTagContainer();

            container.GameplayTags.AddRange(SourceTags);
            container.FillParentTags();
            return(container);
        }
Пример #5
0
 /**
  * Adds all the tags that match between the two specified containers to this container.  WARNING: This matches any
  * parent tag in A, not just exact matches!  So while this should be the union of the container this is called on with
  * the intersection of OtherA and OtherB, it's not exactly that.  Since OtherB matches against its parents, any tag
  * in OtherA which has a parent match with a parent of OtherB will count.  foreachexample, if OtherA has Color.Green
  * and OtherB has Color.Red, that will count as a match due to the Color parent match!
  * If you want an exact match, you need to call A.FilterExact(B) (above) to get the intersection of A with B.
  * If you need the disjunctive union (the union of two sets minus their intersection), use AppendTags to create
  * Union, FilterExact to create Intersection, and then call Union.RemoveTags(Intersection).
  *
  * @param OtherA TagContainer that has the matching tags you want to add to this container, these tags have their parents expanded
  * @param OtherB TagContainer used to check foreachmatching tags.  If the tag matches on any parent, it counts as a match.
  *
  * 将OtherA 匹配 OtherB 的子集添加进来
  */
 public void AppendMatchingTags(CGameplayTagContainer OtherA, CGameplayTagContainer OtherB)
 {
     foreach (CGameplayTag otherATag in OtherA.GameplayTags)
     {
         if (otherATag.MatchesAny(OtherB))
         {
             AddTag(otherATag);
         }
     }
 }
Пример #6
0
        /// <summary>
        /// 返回包含本tag以及所有父亲tag的container
        /// 比如传入的a.b.c 那么 此container会包含a, a.b, a.b.c
        /// </summary>
        public CGameplayTagContainer RequestGameplayTagParents(CGameplayTag GameplayTag)
        {
            CGameplayTagContainer container = GetSingleTagContainer(GameplayTag);

            if (container != null)
            {
                return(container.GetGameplayTagParents());
            }
            return(null);
        }
Пример #7
0
        /// <summary>
        /// 返回一个新的container, 精确的包含了本container的所有GameplayTags和ParentTags
        /// </summary>
        public CGameplayTagContainer GetGameplayTagParents()
        {
            CGameplayTagContainer container = new CGameplayTagContainer(GameplayTags);

            foreach (var item in ParentTags)
            {
                container.GameplayTags.AddUnique(item);
            }

            return(container);
        }
Пример #8
0
        /**
         * Adds all the tags from one container to this container
         * NOTE: From set theory, this effectively is the union of the container this is called on with Other.
         *
         * @param Other TagContainer that has the tags you want to add to this container
         *
         * 将other的gameplaytags添加到本gameplaytags列表
         * 将other的parent tags添加到本parenttags列表
         */
        public void AppendTags(CGameplayTagContainer Other)
        {
            foreach (CGameplayTag tag in Other.GameplayTags)
            {
                GameplayTags.AddUnique(tag);
            }

            foreach (CGameplayTag tag in Other.ParentTags)
            {
                ParentTags.AddUnique(tag);
            }
        }
Пример #9
0
        /// <summary>
        /// 获取传入tag所有的子tag组成的container, 不包含传入tag
        /// 例如传入a.b, 则返回的conatiner包含a.b.c, a.b.d, a.b.c.e
        /// </summary>
        public CGameplayTagContainer RequestGameplayTagChildren(CGameplayTag GameplayTag)
        {
            CGameplayTagContainer TagContainer = new CGameplayTagContainer();

            CGameplayTagNode GameplayTagNode = FindTagNode(GameplayTag);

            if (GameplayTagNode.IsValid())
            {
                AddChildrenTags(TagContainer, GameplayTagNode, true, true);
            }
            return(TagContainer);
        }
Пример #10
0
        /// <summary>
        /// 获取所有的gameplay tag
        /// 如果你只添加了a.b.c那么其实会有3个tag--a, a.b, a.b.c
        /// </summary>
        public void RequestAllGameplayTags(CGameplayTagContainer TagContainer, bool OnlyIncludeDictionaryTags)
        {
            foreach (KeyValuePair <string, CGameplayTagNode> item in GameplayTagNodeMap)
            {
                if (OnlyIncludeDictionaryTags)
                {
                    continue;
                }

                var tag = item.Value.GetCompleteTag();
                TagContainer.AddTagFast(tag);
            }
        }
Пример #11
0
        /**
         *返回一个新的container, 这个container包含的gameplaytag满足是本tag和OtherContainer的精确交集
         */
        public CGameplayTagContainer FilterExact(CGameplayTagContainer OtherContainer)
        {
            CGameplayTagContainer container = new CGameplayTagContainer();

            foreach (CGameplayTag tag in GameplayTags)
            {
                if (tag.MatchesAnyExact(OtherContainer))
                {
                    container.AddTagFast(tag);
                }
            }

            return(container);
        }
Пример #12
0
        /** 添加InTag所在的container的parent tags 到 本ParentTags中*/
        protected void AddParentsForTag(CGameplayTag InTag)
        {
            CGameplayTagContainer inContainer = CGameplayTagsManager.Instance.GetSingleTagContainer(InTag);

            if (inContainer == null)
            {
                return;
            }

            // Add Parent tags from this tag to our own
            foreach (CGameplayTag ParentTag in inContainer.ParentTags)
            {
                ParentTags.AddUnique(ParentTag);
            }
        }
Пример #13
0
        /**
         * GameplayTags 是否包含ContainerToCheck
         * {"A.1","B.1"}.HasAll({"A","B"}) will return False
         */
        public bool HasAllExact(CGameplayTagContainer ContainerToCheck)
        {
            if (ContainerToCheck.IsEmpty())
            {
                return(true);
            }

            foreach (CGameplayTag OtherTag in ContainerToCheck.GameplayTags)
            {
                if (!GameplayTags.Contains(OtherTag))
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #14
0
        /**
         * 本container是否包含ContainerToCheck的任意一个tag, 连ParentTags都会比较
         * {"A.1"}.HasAny({"A","B"}) will return True, {"A"}.HasAny({"A.1","B"}) will return False
         */
        public bool HasAny(CGameplayTagContainer ContainerToCheck)
        {
            if (ContainerToCheck.IsEmpty())
            {
                return(false);
            }

            foreach (CGameplayTag otherTag in ContainerToCheck.GameplayTags)
            {
                if (GameplayTags.Contains(otherTag) || ParentTags.Contains(otherTag))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #15
0
        /**
         * GameplayTags 和 ParentTags 是否包含ContainerToCheck
         * * {"A.1","B.1"}.HasAll({"A","B"}) will return True, {"A","B"}.HasAll({"A.1","B.1"}) will return False
         */
        public bool HasAll(CGameplayTagContainer ContainerToCheck)
        {
            //ContainerToCheck什么都没有,所以肯定返回true
            if (ContainerToCheck.IsEmpty())
            {
                return(true);
            }

            foreach (CGameplayTag OtherTag in ContainerToCheck.GameplayTags)
            {
                if (!GameplayTags.Contains(OtherTag) && !ParentTags.Contains(OtherTag))
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #16
0
        /**
         * Removes all tags in TagsToRemove from this container
         *
         * @param TagsToRemove	Tags to remove from the container
         */
        public void RemoveTags(CGameplayTagContainer TagsToRemove)
        {
            bool removed = false;

            foreach (var item in TagsToRemove.GameplayTags)
            {
                bool r = GameplayTags.Remove(item);
                if (r)
                {
                    removed = true;
                }
            }

            if (removed)
            {
                FillParentTags();
            }
        }
Пример #17
0
        /** 评估传入的tag是否满足query的查询条件 */
        public bool Eval(CGameplayTagContainer Tags)
        {
            CurStreamIdx = 0;
            if (bReadError)
            {
                return(false);
            }

            Version = GetToken();
            bool bRet = false;

            bool bHasRootExpression = (GetToken() != 0);

            if (!bReadError && bHasRootExpression)
            {
                bRet = EvalExpr(Tags);
            }

            return(bRet);
        }
Пример #18
0
        private bool EvalNoTagsMatch(CGameplayTagContainer Tags, bool bSkip)
        {
            // parse tagset
            byte NumTags = GetToken();

            if (bReadError)
            {
                return(false);
            }

            if (bSkip)
            {
                GetTokenNext(NumTags);
                if (bReadError)
                {
                    return(false);
                }
            }
            else
            {
                //交叉比较, 如果有一个就结果失败
                for (byte Idx = 0; Idx < NumTags; ++Idx)
                {
                    byte TagIdx = GetToken();
                    if (bReadError)
                    {
                        return(false);
                    }

                    CGameplayTag Tag     = Query.GetTagFromIndex(TagIdx);
                    bool         bHasTag = Tags.HasTag(Tag);
                    if (bHasTag)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #19
0
        /// <summary>
        /// 将GameplayTagNode的children node对应的tag添加到TagContainer中去
        /// RecurseAll表示在树状节点中, 就添加一层child还是循环一直往下找
        /// </summary>
        private void AddChildrenTags(CGameplayTagContainer TagContainer, CGameplayTagNode GameplayTagNode,
                                     bool RecurseAll = true, bool OnlyIncludeDictionaryTags = false)
        {
            if (!GameplayTagNode.IsValid())
            {
                return;
            }

            var ChildrenNodes = GameplayTagNode.GetChildTagNodes();

            foreach (CGameplayTagNode ChildNode in ChildrenNodes)
            {
                if (!ChildNode.IsValid())
                {
                    continue;
                }

                TagContainer.AddTag(ChildNode.GetCompleteTag());
                if (RecurseAll)
                {
                    AddChildrenTags(TagContainer, ChildNode, true, OnlyIncludeDictionaryTags);
                }
            }
        }
Пример #20
0
 public CGameplayTagQueryExpression AddTags(CGameplayTagContainer Tags)
 {
     TagSet.AddRange(Tags.GameplayTags);
     return(this);
 }
Пример #21
0
        /**
         * 创建 有完全没有tag匹配的查询
         */
        public static FGameplayTagQuery MakeQuery_MatchNoTags(CGameplayTagContainer InTags)
        {
            var qe = new CGameplayTagQueryExpression();

            return(BuildQuery(qe.NoTagsMatch().AddTags(InTags)));
        }
Пример #22
0
 /**
  * 清理现有tag, 用传入的tag填充
  * Replaces existing tags with passed in tags. Does not modify the tag query expression logic.
  * Useful when you need to cache off and update often used query.
  */
 public void ReplaceTagsFast(CGameplayTagContainer Tags)
 {
     TagDictionary.Clear();
     TagDictionary.AddRange(Tags.GameplayTags);
 }
Пример #23
0
        /** Tags 是否有匹配的标签. */
        public bool Matches(CGameplayTagContainer Tags)
        {
            FQueryEvaluator eval = new FQueryEvaluator(this);

            return(eval.Eval(Tags));
        }