// Copyright (c) 2026 Reignance Studios. MIT License, see LICENSE. #include "RSAsyncWaitTagCount.h" #include "AbilitySystemComponent.h" #include "RSAbilitySystemLibrary.h" URSAsyncWaitTagCount* URSAsyncWaitTagCount::WaitGameplayTagCount(AActor* Actor, FGameplayTag Tag, bool bFireInitialCount) { URSAsyncWaitTagCount* Action = NewObject(); Action->WeakASC = URSAbilitySystemLibrary::FindAbilitySystemComponent(Actor); Action->WatchedTag = Tag; Action->bFireInitial = bFireInitialCount; Action->RegisterWithGameInstance(Actor); return Action; } void URSAsyncWaitTagCount::Activate() { UAbilitySystemComponent* ASC = WeakASC.Get(); if (!ASC || !WatchedTag.IsValid()) { // Common on clients: the PlayerState (and its ASC) has not replicated yet. // Retry from OnRep_PlayerState instead of polling. Cancel(); return; } // AnyCountChange, not NewOrRemoved: stacks going from 2 to 3 matter to a UI too. Binding = ASC->RegisterGameplayTagEvent(WatchedTag, EGameplayTagEventType::AnyCountChange) .AddUObject(this, &URSAsyncWaitTagCount::HandleTagChanged); if (bFireInitial) { OnCountChanged.Broadcast(WatchedTag, ASC->GetTagCount(WatchedTag)); } } void URSAsyncWaitTagCount::HandleTagChanged(const FGameplayTag Tag, int32 NewCount) { OnCountChanged.Broadcast(Tag, NewCount); } void URSAsyncWaitTagCount::Cancel() { if (UAbilitySystemComponent* ASC = WeakASC.Get()) { if (Binding.IsValid()) { ASC->UnregisterGameplayTagEvent(Binding, WatchedTag, EGameplayTagEventType::AnyCountChange); } } Binding.Reset(); Super::Cancel(); }