/** * 添加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); }
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); }
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); }
/// <summary> /// 根据传入的tag列表, 创建container /// </summary> public static CGameplayTagContainer CreateFromArray(List <CGameplayTag> SourceTags) { CGameplayTagContainer container = new CGameplayTagContainer(); container.GameplayTags.AddRange(SourceTags); container.FillParentTags(); return(container); }
/** * 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); } } }
/// <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); }
/// <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); }
/** * 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); } }
/// <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); }
/// <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); } }
/** *返回一个新的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); }
/** 添加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); } }
/** * 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); }
/** * 本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); }
/** * 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); }
/** * 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(); } }
/** 评估传入的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); }
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); }
/// <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); } } }
public CGameplayTagQueryExpression AddTags(CGameplayTagContainer Tags) { TagSet.AddRange(Tags.GameplayTags); return(this); }
/** * 创建 有完全没有tag匹配的查询 */ public static FGameplayTagQuery MakeQuery_MatchNoTags(CGameplayTagContainer InTags) { var qe = new CGameplayTagQueryExpression(); return(BuildQuery(qe.NoTagsMatch().AddTags(InTags))); }
/** * 清理现有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); }
/** Tags 是否有匹配的标签. */ public bool Matches(CGameplayTagContainer Tags) { FQueryEvaluator eval = new FQueryEvaluator(this); return(eval.Eval(Tags)); }