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; }
FGameplayCueViewInfo * FGameplayCueHandler::GetBestMatchingView(EGameplayCueEvent::Type Type, const FGameplayTag BaseTag, bool InstigatorLocal, bool TargetLocal) { IGameplayTagsModule& GameplayTagsModule = IGameplayTagsModule::Get(); FGameplayTagContainer TagAndParentsContainer = GameplayTagsModule.GetGameplayTagsManager().RequestGameplayTagParents(BaseTag); for (auto InnerTagIt = TagAndParentsContainer.CreateConstIterator(); InnerTagIt; ++InnerTagIt) { FGameplayTag Tag = *InnerTagIt; for (UGameplayCueView * Def : Definitions) { for (FGameplayCueViewInfo & View : Def->Views) { if (View.CueType == Type && (!View.InstigatorLocalOnly || InstigatorLocal) && (!View.TargetLocalOnly || TargetLocal) && View.Tags.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { return &View; } } } } return NULL; }
bool FGameplayTagRequirements::RequirementsMet(const FGameplayTagContainer& Container) const { bool HasRequired = Container.MatchesAll(RequireTags, true); bool HasIgnored = Container.MatchesAny(IgnoreTags, false); return HasRequired && !HasIgnored; }
void FGameplayTagContainerCustomization::RefreshTagList() { // Rebuild Editable Containers as container references can become unsafe BuildEditableContainerList(); // Clear the list TagNames.Empty(); // Add tags to list for (int32 ContainerIdx = 0; ContainerIdx < EditableContainers.Num(); ++ContainerIdx) { FGameplayTagContainer* Container = EditableContainers[ContainerIdx].TagContainer; if (Container) { for (auto It = Container->CreateConstIterator(); It; ++It) { TagNames.Add(MakeShareable(new FString(It->ToString()))); } } } // Refresh the slate list if( TagListView.IsValid() ) { TagListView->RequestListRefresh(); } }
FGameplayTagContainer UGameplayTagsManager::RequestGameplayTagParents(const FGameplayTag& GameplayTag) const { FGameplayTagContainer TagContainer; TagContainer.AddTag(GameplayTag); AddParentTags(TagContainer, GameplayTag); return TagContainer; }
UGameplayTagReponseTable::UGameplayTagReponseTable(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { // Make an empty tag query. We will actually fill the tag out prior to evaluating the query with ::MakeQuery FGameplayTagContainer Container; Container.AddTagFast(FGameplayTag()); Query = FGameplayEffectQuery::MakeQuery_MatchAllOwningTags(Container); }
void FGameplayTagCountContainer::UpdateTagMap_Internal(const FGameplayTag& Tag, int32 CountDelta) { const bool bTagAlreadyExplicitlyExists = ExplicitTags.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit); // Need special case handling to maintain the explicit tag list correctly, adding the tag to the list if it didn't previously exist and a // positive delta comes in, and removing it from the list if it did exist and a negative delta comes in. if (!bTagAlreadyExplicitlyExists) { // Brand new tag with a positive delta needs to be explicitly added if (CountDelta > 0) { ExplicitTags.AddTag(Tag); } // Block attempted reduction of non-explicit tags, as they were never truly added to the container directly else { ABILITY_LOG(Warning, TEXT("Attempted to remove tag: %s from tag count container, but it is not explicitly in the container!"), *Tag.ToString()); return; } } else if (CountDelta < 0) { // Existing tag with a negative delta that would cause a complete removal needs to be explicitly removed; Count will be updated correctly below, // so that part is skipped for now int32& ExistingCount = GameplayTagCountMap.FindOrAdd(Tag); if ((ExistingCount + CountDelta) <= 0) { ExplicitTags.RemoveTag(Tag); } } // Check if change delegates are required to fire for the tag or any of its parents based on the count change FGameplayTagContainer TagAndParentsContainer = IGameplayTagsModule::Get().GetGameplayTagsManager().RequestGameplayTagParents(Tag); for (auto CompleteTagIt = TagAndParentsContainer.CreateConstIterator(); CompleteTagIt; ++CompleteTagIt) { const FGameplayTag& CurTag = *CompleteTagIt; // Get the current count of the specified tag. NOTE: Stored as a reference, so subsequent changes propogate to the map. int32& TagCount = GameplayTagCountMap.FindOrAdd(CurTag); const int32 OldCount = TagCount; // Apply the delta to the count in the map TagCount = FMath::Max(TagCount + CountDelta, 0); // If a significant change (new addition or total removal) occurred, trigger related delegates if (OldCount == 0 || TagCount == 0) { OnAnyTagChangeDelegate.Broadcast(CurTag, TagCount); FOnGameplayEffectTagCountChanged* CountChangeDelegate = GameplayTagEventMap.Find(CurTag); if (CountChangeDelegate) { CountChangeDelegate->Broadcast(CurTag, TagCount); } } } }
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); } } } }
FGameplayTagContainer FGameplayTagContainer::GetGameplayTagParents() const { FGameplayTagContainer ResultContainer; ResultContainer.AppendTags(*this); for (TArray<FGameplayTag>::TConstIterator TagIterator(GameplayTags); TagIterator; ++TagIterator) { FGameplayTagContainer ParentTags = IGameplayTagsModule::Get().GetGameplayTagsManager().RequestGameplayTagParents(*TagIterator); ResultContainer.AppendTags(ParentTags); } return ResultContainer; }
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; } }
void FGameplayCueHandler::GameplayCueActivated(const FGameplayTagContainer& GameplayCueTags, float NormalizedMagnitude, const FGameplayEffectContextHandle& EffectContext) { check(Owner); bool InstigatorLocal = EffectContext.IsLocallyControlled(); bool TargetLocal = OwnerIsLocallyControlled(); for (auto TagIt = GameplayCueTags.CreateConstIterator(); TagIt; ++TagIt) { if (FGameplayCueViewInfo* View = GetBestMatchingView(EGameplayCueEvent::OnActive, *TagIt, InstigatorLocal, TargetLocal)) { View->SpawnViewEffects(Owner, NULL, EffectContext); } FName MatchedTag; UFunction *Func = UAbilitySystemGlobals::Get().GetGameplayCueFunction(*TagIt, Owner->GetClass(), MatchedTag); if (Func) { FGameplayCueParameters Params; Params.NormalizedMagnitude = NormalizedMagnitude; Params.EffectContext = EffectContext; IGameplayCueInterface::DispatchBlueprintCustomHandler(Owner, Func, EGameplayCueEvent::OnActive, Params); } } }
void IGameplayCueInterface::HandleGameplayCues(AActor *Self, const FGameplayTagContainer& GameplayCueTags, EGameplayCueEvent::Type EventType, FGameplayCueParameters Parameters) { for (auto TagIt = GameplayCueTags.CreateConstIterator(); TagIt; ++TagIt) { HandleGameplayCue(Self, *TagIt, EventType, Parameters); } }
void UEditableGameplayTagQueryExpression::EmitTagTokens(FGameplayTagContainer const& TagsToEmit, TArray<uint8>& TokenStream, TArray<FGameplayTag>& TagDictionary, FString* DebugString) const { uint8 const NumTags = (uint8)TagsToEmit.Num(); TokenStream.Add(NumTags); bool bFirstTag = true; for (auto T : TagsToEmit) { int32 TagIdx = TagDictionary.AddUnique(T); check(TagIdx <= 255); TokenStream.Add((uint8)TagIdx); if (DebugString) { if (bFirstTag == false) { DebugString->Append(TEXT(",")); } DebugString->Append(TEXT(" ")); DebugString->Append(T.ToString()); } bFirstTag = false; } }
void FGAEffectModifierContainer::AddModifier(const FGAEffectModifierSpec& ModSpec, const FGameplayTagContainer& Tags, const FGAEffectHandle HandleIn, TSharedPtr<FGAActiveDuration> EffectPtr) { FString complexString = Tags.ToString(); FString simpleString = Tags.ToStringSimple(); FName test(*simpleString); for (const FGameplayTag& tag : Tags) { FGAEffectModifier& mods = Modifiers.FindOrAdd(tag); FGAModifier modifier(ModSpec.Mod, ModSpec.DirectModifier.Value, EffectPtr); modifier.ModifierType = ModSpec.ModifierType; mods.AddBonus(modifier, HandleIn); } }
void FGameplayTagCountContainer::Notify_StackCountChange(const FGameplayTag& Tag) { // The purpose of this function is to let anyone listening on the EGameplayTagEventType::AnyCountChange event know that the // stack count of a GE that was backing this GE has changed. We do not update our internal map/count with this info, since that // map only counts the number of GE/sources that are giving that tag. FGameplayTagContainer TagAndParentsContainer = IGameplayTagsModule::Get().GetGameplayTagsManager().RequestGameplayTagParents(Tag); for (auto CompleteTagIt = TagAndParentsContainer.CreateConstIterator(); CompleteTagIt; ++CompleteTagIt) { const FGameplayTag& CurTag = *CompleteTagIt; FDelegateInfo* DelegateInfo = GameplayTagEventMap.Find(CurTag); if (DelegateInfo) { int32 TagCount = GameplayTagCountMap.FindOrAdd(CurTag); DelegateInfo->OnAnyChange.Broadcast(CurTag, TagCount); } } }
void UK2Node_GameplayCueEvent::GetMenuEntries(FGraphContextMenuBuilder& Context) const { Super::GetMenuEntries(Context); if (!IsCompatibleWithGraph(Context.CurrentGraph)) { return; } const FString FunctionCategory(TEXT("GameplayCue Event")); IGameplayTagsModule& GameplayTagsModule = IGameplayTagsModule::Get(); FGameplayTag RootTag = GameplayTagsModule.GetGameplayTagsManager().RequestGameplayTag(FName(TEXT("GameplayCue"))); FGameplayTagContainer CueTags = GameplayTagsModule.GetGameplayTagsManager().RequestGameplayTagChildren(RootTag); // Add a root GameplayCue function as a default CueTags.AddTag(RootTag); // Fixme: need to check if this function is already defined so that it can be reimplemented // -Checking MyBlueprint->GeneratedClass isn't enough since they may have added an event and not recompiled // -FEdGraphSchemaAction_K2AddCustomEvent does not check names/always ensures a valid name // -FEdGraphSchemaAction_K2AddEvent does check and recenters - but it looks at EventSignatureName/EventSignatureClass for equality and that // won't work here. // // Probably need a new EdGraphSchemaAction to do this properly. For now this is ok since they will get a compile error if they do drop in // two of the same GameplayCue even Nodes and it should be pretty clear that they can't do that. for (auto It = CueTags.CreateConstIterator(); It; ++It) { FGameplayTag Tag = *It; UK2Node_GameplayCueEvent* NodeTemplate = Context.CreateTemplateNode<UK2Node_GameplayCueEvent>(); NodeTemplate->CustomFunctionName = Tag.GetTagName(); const FString Category = FunctionCategory; const FText MenuDesc = NodeTemplate->GetNodeTitle(ENodeTitleType::ListView); const FString Tooltip = NodeTemplate->GetTooltipText().ToString(); const FString Keywords = NodeTemplate->GetKeywords(); TSharedPtr<FEdGraphSchemaAction_K2NewNode> NodeAction = FK2ActionMenuBuilder::AddNewNodeAction(Context, Category, MenuDesc, Tooltip, 0, Keywords); NodeAction->NodeTemplate = NodeTemplate; } }
void FGameplayTagCountContainer::UpdateTagCount(const FGameplayTagContainer& Container, int32 CountDelta) { if (CountDelta != 0) { for (auto TagIt = Container.CreateConstIterator(); TagIt; ++TagIt) { UpdateTagMap_Internal(*TagIt, CountDelta); } } }
void SGameplayTagWidget::OnTagChecked(TSharedPtr<FGameplayTagNode> NodeChecked) { FScopedTransaction Transaction( LOCTEXT("GameplayTagWidget_AddTags", "Add Gameplay Tags") ); UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); for (int32 ContainerIdx = 0; ContainerIdx < TagContainers.Num(); ++ContainerIdx) { TWeakPtr<FGameplayTagNode> CurNode(NodeChecked); UObject* OwnerObj = TagContainers[ContainerIdx].TagContainerOwner.Get(); FGameplayTagContainer* Container = TagContainers[ContainerIdx].TagContainer; if (Container) { FGameplayTagContainer EditableContainer = *Container; bool bRemoveParents = false; while (CurNode.IsValid()) { FGameplayTag Tag = TagsManager.RequestGameplayTag(CurNode.Pin()->GetCompleteTag()); if (bRemoveParents == false) { bRemoveParents = true; if (bMultiSelect == false) { EditableContainer.RemoveAllTags(); } EditableContainer.AddTag(Tag); } else { EditableContainer.RemoveTag(Tag); } CurNode = CurNode.Pin()->GetParentTagNode(); } SetContainer(Container, &EditableContainer, OwnerObj); } } }
void FGameplayTagCustomization::OnPropertyValueChanged() { TagName = TEXT(""); if (StructPropertyHandle.IsValid() && EditableContainers.Num() > 0) { TArray<void*> RawStructData; StructPropertyHandle->AccessRawData(RawStructData); if (RawStructData.Num() > 0) { FGameplayTag* Tag = (FGameplayTag*)(RawStructData[0]); FGameplayTagContainer* Container = EditableContainers[0].TagContainer; if (Tag && Container) { Container->RemoveAllTags(); Container->AddTag(*Tag); TagName = Tag->ToString(); } } } }
FReply FGameplayTagContainerCustomization::OnClearAllButtonClicked() { FScopedTransaction Transaction(LOCTEXT("GameplayTagContainerCustomization_RemoveAllTags", "Remove All Gameplay Tags")); for (int32 ContainerIdx = 0; ContainerIdx < EditableContainers.Num(); ++ContainerIdx) { UObject* OwnerObj = EditableContainers[ContainerIdx].TagContainerOwner; FGameplayTagContainer* Container = EditableContainers[ContainerIdx].TagContainer; if (OwnerObj && Container) { OwnerObj->PreEditChange(StructPropertyHandle->GetProperty()); FGameplayTagContainer EmptyContainer; StructPropertyHandle->SetValueFromFormattedString(EmptyContainer.ToString()); OwnerObj->PostEditChange(); RefreshTagList(); } } return FReply::Handled(); }
void UGameplayCueManager::HandleGameplayCues(AActor* TargetActor, const FGameplayTagContainer& GameplayCueTags, EGameplayCueEvent::Type EventType, const FGameplayCueParameters& Parameters) { if (GameplayCueRunOnDedicatedServer == 0 && IsDedicatedServerForGameplayCue()) { return; } for (auto It = GameplayCueTags.CreateConstIterator(); It; ++It) { HandleGameplayCue(TargetActor, *It, EventType, Parameters); } }
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 FGameplayTagContainer::AppendTags(FGameplayTagContainer const& Other) { SCOPE_CYCLE_COUNTER(STAT_FGameplayTagContainer_AppendTags); GameplayTags.Reserve(Other.Num()); //add all the tags for(TArray<FGameplayTag>::TConstIterator It(Other.GameplayTags); It; ++It) { AddTag(*It); } }
FGameplayTagContainer FGameplayTagContainer::Filter(const FGameplayTagContainer& OtherContainer, TEnumAsByte<EGameplayTagMatchType::Type> TagMatchType, TEnumAsByte<EGameplayTagMatchType::Type> OtherTagMatchType) const { SCOPE_CYCLE_COUNTER(STAT_FGameplayTagContainer_Filter); FGameplayTagContainer ResultContainer; UGameplayTagsManager& TagManager = IGameplayTagsModule::GetGameplayTagsManager(); for (TArray<FGameplayTag>::TConstIterator OtherIt(OtherContainer.GameplayTags); OtherIt; ++OtherIt) { for (TArray<FGameplayTag>::TConstIterator It(this->GameplayTags); It; ++It) { if (TagManager.GameplayTagsMatch(*It, TagMatchType, *OtherIt, OtherTagMatchType) == true) { ResultContainer.AddTag(*It); } } } return ResultContainer; }
void UK2Node_GameplayCueEvent::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const { // actions get registered under specific object-keys; the idea is that // actions might have to be updated (or deleted) if their object-key is // mutated (or removed)... here we use the node's class (so if the node // type disappears, then the action should go with it) UClass* ActionKey = GetClass(); // to keep from needlessly instantiating a UBlueprintNodeSpawner, first // check to make sure that the registrar is looking for actions of this type // (could be regenerating actions for a specific asset, and therefore the // registrar would only accept actions corresponding to that asset) if (!ActionRegistrar.IsOpenForRegistration(ActionKey)) { return; } auto CustomizeCueNodeLambda = [](UEdGraphNode* NewNode, bool bIsTemplateNode, FName TagName) { UK2Node_GameplayCueEvent* EventNode = CastChecked<UK2Node_GameplayCueEvent>(NewNode); EventNode->CustomFunctionName = TagName; }; IGameplayTagsModule& GameplayTagsModule = IGameplayTagsModule::Get(); FGameplayTag RootTag = GameplayTagsModule.GetGameplayTagsManager().RequestGameplayTag(FName(TEXT("GameplayCue"))); FGameplayTagContainer CueTags = GameplayTagsModule.GetGameplayTagsManager().RequestGameplayTagChildren(RootTag); // Add a root GameplayCue function as a default CueTags.AddTag(RootTag); for (auto TagIt = CueTags.CreateConstIterator(); TagIt; ++TagIt) { UBlueprintNodeSpawner::FCustomizeNodeDelegate PostSpawnDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(CustomizeCueNodeLambda, TagIt->GetTagName()); UBlueprintNodeSpawner* NodeSpawner = UBlueprintEventNodeSpawner::Create(GetClass(), TagIt->GetTagName()); check(NodeSpawner != nullptr); NodeSpawner->CustomizeNodeDelegate = PostSpawnDelegate; ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner); } }
void FQueryEvaluator::ReadEditableQueryTags(UEditableGameplayTagQueryExpression* EditableQueryExpr) { // find the tag container to read into FGameplayTagContainer* Tags = nullptr; if (EditableQueryExpr->IsA(UEditableGameplayTagQueryExpression_AnyTagsMatch::StaticClass())) { Tags = &((UEditableGameplayTagQueryExpression_AnyTagsMatch*)EditableQueryExpr)->Tags; } else if (EditableQueryExpr->IsA(UEditableGameplayTagQueryExpression_AllTagsMatch::StaticClass())) { Tags = &((UEditableGameplayTagQueryExpression_AllTagsMatch*)EditableQueryExpr)->Tags; } else if (EditableQueryExpr->IsA(UEditableGameplayTagQueryExpression_NoTagsMatch::StaticClass())) { Tags = &((UEditableGameplayTagQueryExpression_NoTagsMatch*)EditableQueryExpr)->Tags; } ensure(Tags); if (Tags) { // parse tag set int32 const NumTags = GetToken(); if (bReadError) { return; } for (int32 Idx = 0; Idx < NumTags; ++Idx) { int32 const TagIdx = GetToken(); if (bReadError) { return; } FGameplayTag const Tag = Query.GetTagFromIndex(TagIdx); Tags->AddTag(Tag); } } }
void SGameplayTagWidget::UncheckChildren(TSharedPtr<FGameplayTagNode> NodeUnchecked, FGameplayTagContainer& EditableContainer) { UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); FGameplayTag Tag = TagsManager.RequestGameplayTag(NodeUnchecked->GetCompleteTag()); EditableContainer.RemoveTag(Tag); // Uncheck Children for (const auto& ChildNode : NodeUnchecked->GetChildTagNodes()) { UncheckChildren(ChildNode, EditableContainer); } }
void FGameplayCueHandler::GameplayCueExecuted(const FGameplayTagContainer& GameplayCueTags, float NormalizedMagnitude, const FGameplayEffectContextHandle& EffectContext) { check(Owner); bool InstigatorLocal = EffectContext.IsLocallyControlled(); bool TargetLocal = OwnerIsLocallyControlled(); for (auto TagIt = GameplayCueTags.CreateConstIterator(); TagIt; ++TagIt) { if (FGameplayCueViewInfo* View = GetBestMatchingView(EGameplayCueEvent::Executed, *TagIt, InstigatorLocal, TargetLocal)) { View->SpawnViewEffects(Owner, NULL, EffectContext); } } }
float FGAEffectModifiersContainer::GatherMods(const FGameplayTagContainer& TagsIn, const TMap<FGAGameEffectHandle, TArray<FGAGameEffectModifier>>& Data) { //possible optimization when needed - create separate thread. float ModifierVal = 0; float Add = 0; float Multiply = 1; float Subtract = 0; float Divide = 1; float PercentageAdd = 0; float PercentageSubtract = 0; for (auto It = Data.CreateConstIterator(); It; ++It) { for (const FGAGameEffectModifier& Test : It->Value) { if (TagsIn.MatchesAll(Test.RequiredTags, false)) { switch (Test.ModType) { case EGAAttributeMod::Add: Add += Test.Value; break; case EGAAttributeMod::Multiply: Multiply += Test.Value; break; case EGAAttributeMod::Subtract: Subtract += Test.Value; break; case EGAAttributeMod::Divide: Divide += Test.Value; break; case EGAAttributeMod::PercentageAdd: PercentageAdd += Test.Value; break; case EGAAttributeMod::PercentageSubtract: PercentageSubtract += Test.Value; break; default: break; } } } } ModifierVal = ((Add - Subtract) * Multiply) / Divide; ModifierVal = ModifierVal + (ModifierVal * PercentageAdd); ModifierVal = ModifierVal - (ModifierVal * PercentageSubtract); SCOPE_CYCLE_COUNTER(STAT_GatherModifiers); return ModifierVal; }
void FGameplayTagCustomization::OnTagChanged() { TagName = TEXT(""); if (StructPropertyHandle.IsValid() && EditableContainers.Num() > 0) { TArray<void*> RawStructData; StructPropertyHandle->AccessRawData(RawStructData); if (RawStructData.Num() > 0) { FGameplayTag* Tag = (FGameplayTag*)(RawStructData[0]); // Update Tag from the one selected from list FGameplayTagContainer* Container = EditableContainers[0].TagContainer; if (Tag && Container) { for (auto It = Container->CreateConstIterator(); It; ++It) { *Tag = *It; TagName = It->ToString(); } } } } }