bool UGameplayTagsManager::AddLeafTagToContainer(FGameplayTagContainer& TagContainer, FGameplayTag& Tag) { // Check tag is not already in container if (TagContainer.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { return true; } // Check tag is not just a parent of an existing tag in the container for (auto It = TagContainer.CreateConstIterator(); It; ++It) { FGameplayTagContainer ParentTags = RequestGameplayTagParents(*It); if (ParentTags.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { return false; } } // Remove any tags in the container that are a parent to this tag FGameplayTagContainer ParentTags = RequestGameplayTagParents(Tag); for (auto It = ParentTags.CreateConstIterator(); It; ++It) { if (TagContainer.HasTag(*It, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { TagContainer.RemoveTag(*It); } } // Add the tag TagContainer.AddTag(Tag); return true; }
void SGameplayTagWidget::VerifyAssetTagValidity() { FGameplayTagContainer LibraryTags; // Create a set that is the library of all valid tags TArray< TSharedPtr<FGameplayTagNode> > NodeStack; UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); TagsManager.GetFilteredGameplayRootTags(TEXT(""), NodeStack); while (NodeStack.Num() > 0) { TSharedPtr<FGameplayTagNode> CurNode = NodeStack.Pop(); if (CurNode.IsValid()) { LibraryTags.AddTag(TagsManager.RequestGameplayTag(CurNode->GetCompleteTag())); NodeStack.Append(CurNode->GetChildTagNodes()); } } // Find and remove any tags on the asset that are no longer in the library for (int32 ContainerIdx = 0; ContainerIdx < TagContainers.Num(); ++ContainerIdx) { UObject* OwnerObj = TagContainers[ContainerIdx].TagContainerOwner.Get(); FGameplayTagContainer* Container = TagContainers[ContainerIdx].TagContainer; if (Container) { FGameplayTagContainer EditableContainer = *Container; FGameplayTagContainer InvalidTags; for (auto It = Container->CreateConstIterator(); It; ++It) { if (!LibraryTags.HasTag(*It, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { InvalidTags.AddTag(*It); } } if (InvalidTags.Num() > 0) { FString InvalidTagNames; for (auto InvalidIter = InvalidTags.CreateConstIterator(); InvalidIter; ++InvalidIter) { EditableContainer.RemoveTag(*InvalidIter); InvalidTagNames += InvalidIter->ToString() + TEXT("\n"); } SetContainer(Container, &EditableContainer, OwnerObj); FFormatNamedArguments Arguments; Arguments.Add(TEXT("Objects"), FText::FromString( InvalidTagNames )); FText DialogText = FText::Format( LOCTEXT("GameplayTagWidget_InvalidTags", "Invalid Tags that have been removed: \n\n{Objects}"), Arguments ); OpenMsgDlgInt( EAppMsgType::Ok, DialogText, LOCTEXT("GameplayTagWidget_Warning", "Warning") ); } } } }
void FGameplayTagContainer::AppendMatchingTags(FGameplayTagContainer const& OtherA, FGameplayTagContainer const& OtherB) { SCOPE_CYCLE_COUNTER(STAT_FGameplayTagContainer_AppendMatchingTags); for(TArray<FGameplayTag>::TConstIterator It(OtherA.GameplayTags); It; ++It) { if (OtherB.HasTag(*It, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::IncludeParentTags)) { AddTag(*It); } } }
void SGameplayTagWidget::OnTagUnchecked(TSharedPtr<FGameplayTagNode> NodeUnchecked) { FScopedTransaction Transaction( LOCTEXT("GameplayTagWidget_RemoveTags", "Remove Gameplay Tags")); if (NodeUnchecked.IsValid()) { UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); for (int32 ContainerIdx = 0; ContainerIdx < TagContainers.Num(); ++ContainerIdx) { UObject* OwnerObj = TagContainers[ContainerIdx].TagContainerOwner.Get(); FGameplayTagContainer* Container = TagContainers[ContainerIdx].TagContainer; FGameplayTag Tag = TagsManager.RequestGameplayTag(NodeUnchecked->GetCompleteTag()); if (Container) { FGameplayTagContainer EditableContainer = *Container; EditableContainer.RemoveTag(Tag); TWeakPtr<FGameplayTagNode> ParentNode = NodeUnchecked->GetParentTagNode(); if (ParentNode.IsValid()) { // Check if there are other siblings before adding parent bool bOtherSiblings = false; for (auto It = ParentNode.Pin()->GetChildTagNodes().CreateConstIterator(); It; ++It) { Tag = TagsManager.RequestGameplayTag(It->Get()->GetCompleteTag()); if (EditableContainer.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { bOtherSiblings = true; break; } } // Add Parent if (!bOtherSiblings) { Tag = TagsManager.RequestGameplayTag(ParentNode.Pin()->GetCompleteTag()); EditableContainer.AddTag(Tag); } } // Uncheck Children for (const auto& ChildNode : NodeUnchecked->GetChildTagNodes()) { UncheckChildren(ChildNode, EditableContainer); } SetContainer(Container, &EditableContainer, OwnerObj); } } } }
ECheckBoxState SGameplayTagWidget::IsTagChecked(TSharedPtr<FGameplayTagNode> Node) const { int32 NumValidAssets = 0; int32 NumAssetsTagIsAppliedTo = 0; if (Node.IsValid()) { UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); for (int32 ContainerIdx = 0; ContainerIdx < TagContainers.Num(); ++ContainerIdx) { FGameplayTagContainer* Container = TagContainers[ContainerIdx].TagContainer; if (Container) { NumValidAssets++; FGameplayTag Tag = TagsManager.RequestGameplayTag(Node->GetCompleteTag(), false); if (Tag.IsValid()) { if (Container->HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { ++NumAssetsTagIsAppliedTo; } } } } } if (NumAssetsTagIsAppliedTo == 0) { // Check if any children are tagged for (auto It = Node->GetChildTagNodes().CreateConstIterator(); It; ++It) { if (IsTagChecked(*It) == ECheckBoxState::Checked) { return ECheckBoxState::Checked; } } return ECheckBoxState::Unchecked; } else if (NumAssetsTagIsAppliedTo == NumValidAssets) { return ECheckBoxState::Checked; } else { return ECheckBoxState::Undetermined; } }
bool FQueryEvaluator::EvalNoTagsMatch(FGameplayTagContainer const& Tags, bool bSkip) { bool bShortCircuit = bSkip; // assume true until proven otherwise bool Result = true; // parse tagset int32 const NumTags = GetToken(); if (bReadError) { return false; } for (int32 Idx = 0; Idx < NumTags; ++Idx) { int32 const TagIdx = GetToken(); if (bReadError) { return false; } if (bShortCircuit == false) { FGameplayTag const Tag = Query.GetTagFromIndex(TagIdx); bool const bHasTag = Tags.HasTag(Tag, EGameplayTagMatchType::IncludeParentTags, EGameplayTagMatchType::Explicit); if (bHasTag == true) { // one match is sufficient for a false result bShortCircuit = true; Result = false; } } } return Result; }