void UGameplayAbility_Montage::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo)
{
	if (!CommitAbility(Handle, ActorInfo, ActivationInfo))
	{
		return;
	}

	if (MontageToPlay != NULL && ActorInfo->AnimInstance != NULL && ActorInfo->AnimInstance->GetActiveMontageInstance() == NULL)
	{
		TArray<FActiveGameplayEffectHandle>	AppliedEffects;

		// Apply GameplayEffects
		for (const UGameplayEffect* Effect : GameplayEffectsWhileAnimating)
		{
			FActiveGameplayEffectHandle Handle = ActorInfo->AbilitySystemComponent->ApplyGameplayEffectToSelf(Effect, 1.f, GetEffectContext(ActorInfo));
			if (Handle.IsValid())
			{
				AppliedEffects.Add(Handle);
			}
		}

		float const Duration = ActorInfo->AnimInstance->Montage_Play(MontageToPlay, PlayRate);

		FOnMontageEnded EndDelegate;
		EndDelegate.BindUObject(this, &UGameplayAbility_Montage::OnMontageEnded, ActorInfo->AbilitySystemComponent, AppliedEffects);
		ActorInfo->AnimInstance->Montage_SetEndDelegate(EndDelegate);

		if (SectionName != NAME_None)
		{
			ActorInfo->AnimInstance->Montage_JumpToSection(SectionName);
		}
	}
}
void UGameplayTagReponseTable::Remove(UAbilitySystemComponent* ASC, FActiveGameplayEffectHandle& Handle)
{
	if (Handle.IsValid())
	{
		ASC->RemoveActiveGameplayEffect(Handle);
		Handle.Invalidate();
	}
}
int32 UAbilitySystemBlueprintLibrary::GetActiveGameplayEffectStackCount(FActiveGameplayEffectHandle ActiveHandle)
{
	UAbilitySystemComponent* ASC = ActiveHandle.GetOwningAbilitySystemComponent();
	if (ASC)
	{
		return ASC->GetCurrentStackCount(ActiveHandle);
	}
	return 0;
}
// moved the remove into a common function since now we will need to remove w/o marking it as dirty so we can support updating the aggregators 
void FAggregator::InternalRemoveAggregatorMod(FActiveGameplayEffectHandle ActiveHandle)
{
	if (ActiveHandle.IsValid())
	{
		RemoveModsWithActiveHandle(Mods[EGameplayModOp::Additive], ActiveHandle);
		RemoveModsWithActiveHandle(Mods[EGameplayModOp::Multiplicitive], ActiveHandle);
		RemoveModsWithActiveHandle(Mods[EGameplayModOp::Division], ActiveHandle);
		RemoveModsWithActiveHandle(Mods[EGameplayModOp::Override], ActiveHandle);
	}
}
FString UAbilitySystemBlueprintLibrary::GetActiveGameplayEffectDebugString(FActiveGameplayEffectHandle ActiveHandle)
{
	FString Str;
	UAbilitySystemComponent* ASC = ActiveHandle.GetOwningAbilitySystemComponent();
	if (ASC)
	{
		Str = ASC->GetActiveGEDebugString(ActiveHandle);
	}
	return Str;
}
int32 UAbilitySystemBlueprintLibrary::GetActiveGameplayEffectStackLimitCount(FActiveGameplayEffectHandle ActiveHandle)
{
	UAbilitySystemComponent* ASC = ActiveHandle.GetOwningAbilitySystemComponent();
	if (ASC)
	{
		const UGameplayEffect* ActiveGE = ASC->GetGameplayEffectDefForHandle(ActiveHandle);
		if (ActiveGE)
		{
			return ActiveGE->StackLimitCount;
		}
	}
	return 0;
}
void UGameplayTagReponseTable::AddOrUpdate(UAbilitySystemComponent* ASC, const TSubclassOf<UGameplayEffect>& ResponseGameplayEffect, int32 TotalCount, FActiveGameplayEffectHandle& Handle)
{
	if (ResponseGameplayEffect)
	{
		if (Handle.IsValid())
		{
			ASC->SetActiveGameplayEffectLevel(Handle, TotalCount);
		}
		else
		{
			Handle = ASC->ApplyGameplayEffectToSelf(Cast<UGameplayEffect>(ResponseGameplayEffect->ClassDefaultObject), TotalCount, ASC->GetEffectContext());
		}
	}
}
void FAggregator::RemoveModsWithActiveHandle(TArray<FAggregatorMod>& InMods, FActiveGameplayEffectHandle ActiveHandle)
{
	check(ActiveHandle.IsValid());

	for(int32 idx=InMods.Num()-1; idx >= 0; --idx)
	{
		if (InMods[idx].ActiveHandle == ActiveHandle)
		{
			if (InMods[idx].IsPredicted)
			{
				NumPredictiveMods--;
			}

			InMods.RemoveAtSwap(idx, 1, false);
		}
	}
}