127 lines
4.7 KiB
C++
127 lines
4.7 KiB
C++
#include "GasaEffectActor.h"
|
|
|
|
#include "GasaAbilitySystemComponent_Inlines.h"
|
|
#include "GasaContainers.h"
|
|
using namespace Gasa;
|
|
|
|
AGasaEffectActor::AGasaEffectActor()
|
|
{
|
|
PrimaryActorTick.bCanEverTick = false;
|
|
|
|
RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
|
|
|
|
Level = 1.f;
|
|
|
|
InstantEffectUsage = EInstantEffectUsagePolicy::DoNotApply;
|
|
DurationEffectUsage = DefaultEffectUsagePolicy;
|
|
InfiniteEffectUsage = DefaultEffectUsagePolicy;
|
|
|
|
bDestroyOnEffectRemoval = false;
|
|
}
|
|
|
|
void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap)
|
|
{
|
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
|
FGameplayEffectContextHandle
|
|
Context = AS->MakeEffectContext();
|
|
Context.AddSourceObject(Actor);
|
|
|
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, Level, Context );
|
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
if (bRemoveOnEndOverlap)
|
|
ActiveEffectsToRemove.Add(ActiveEffect, AS);
|
|
}
|
|
|
|
void AGasaEffectActor::OnOverlap(AActor* Actor)
|
|
{
|
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
|
FGameplayEffectContextHandle
|
|
Context = AS->MakeEffectContext();
|
|
Context.AddSourceObject(Actor);
|
|
|
|
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap)
|
|
{
|
|
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
|
|
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
}
|
|
if (DurationEffectClass)
|
|
{
|
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap))
|
|
{
|
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
|
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
|
ActiveDuration = ActiveEffect;
|
|
}
|
|
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
|
AS->RemoveActiveGameplayEffect(ActiveDuration);
|
|
}
|
|
if (InfiniteEffectClass)
|
|
{
|
|
bool bApplyOnOverlap = Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnOverlap);
|
|
if (bApplyOnOverlap)
|
|
{
|
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
|
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
|
ActiveInfinite = ActiveEffect;
|
|
}
|
|
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
|
{
|
|
if (ActiveInfinite.IsValid())
|
|
AS->RemoveActiveGameplayEffect(ActiveInfinite);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AGasaEffectActor::OnEndOverlap(AActor* Actor)
|
|
{
|
|
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
|
|
FGameplayEffectContextHandle
|
|
Context = AS->MakeEffectContext();
|
|
Context.AddSourceObject(Actor);
|
|
|
|
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnEndOverlap)
|
|
{
|
|
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
|
|
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
}
|
|
if (DurationEffectClass)
|
|
{
|
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
|
|
{
|
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
|
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
|
ActiveDuration = ActiveEffect;
|
|
}
|
|
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
|
AS->RemoveActiveGameplayEffect(ActiveDuration);
|
|
}
|
|
if (InfiniteEffectClass)
|
|
{
|
|
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
|
|
{
|
|
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
|
|
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
|
|
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
|
|
ActiveInfinite = ActiveEffect;
|
|
}
|
|
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
|
|
{
|
|
if (ActiveInfinite.IsValid())
|
|
AS->RemoveActiveGameplayEffect(ActiveInfinite);
|
|
}
|
|
}
|
|
|
|
TArray<FActiveGameplayEffectHandle> EffectsRemoved;
|
|
for (ActiveEffectEntry ActiveEffect : ActiveEffectsToRemove)
|
|
{
|
|
if (ActiveEffect.Value != AS)
|
|
continue;
|
|
AS->RemoveActiveGameplayEffect(ActiveEffect.Key, 1);
|
|
EffectsRemoved.Add(ActiveEffect.Key);
|
|
}
|
|
RemoveKeys(ActiveEffectsToRemove, EffectsRemoved);
|
|
}
|