53. Gameplay Effect Delegates

This commit is contained in:
Edward R. Gonzalez 2024-04-25 00:30:54 -04:00
parent ad14d6b3af
commit 901ef9460b
6 changed files with 115 additions and 97 deletions

View File

@ -0,0 +1,16 @@
[/Script/GameplayTags.GameplayTagsSettings]
ImportTagsFromConfig=True
WarnOnInvalidTags=True
ClearInvalidTags=False
AllowEditorTagUnloading=True
AllowGameTagUnloading=False
FastReplication=False
InvalidTagCharacters="\"\',"
+GameplayTagTableList=/Game/Core/DT_PrimaryAttributes.DT_PrimaryAttributes
NumBitsForContainerSize=6
NetIndexFirstBitSegment=16
+GameplayTagList=(Tag="Attributes.Vital.Health",DevComment="")
+GameplayTagList=(Tag="Attributes.Vital.Mana",DevComment="")
+GameplayTagList=(Tag="Attributes.Vital.MaxHealth",DevComment="")
+GameplayTagList=(Tag="Attributes.Vital.MaxMana",DevComment="")

View File

@ -0,0 +1,7 @@
{
"ColumnWidths":
{
"DevComment": 405,
"Tag": 381
}
}

View File

@ -22,28 +22,23 @@ void UGasaAttributeSet::Client_OnRep_Health(FGameplayAttributeData& PrevHealth)
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) ); static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Health, PrevHealth ); GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Health, PrevHealth );
} }
void UGasaAttributeSet::Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth ) void UGasaAttributeSet::Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth )
{ {
// From GAMEPLAYATTRIBUTE_REPNOTIFY // From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) ); static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(UGasaAttributeSetProperty), MaxHealth, GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxHealth, PrevMaxHealth );
PrevMaxHealth);
} }
void UGasaAttributeSet::Client_OnRep_Mana( FGameplayAttributeData& PrevMana ) void UGasaAttributeSet::Client_OnRep_Mana( FGameplayAttributeData& PrevMana )
{ {
// From GAMEPLAYATTRIBUTE_REPNOTIFY // From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) ); static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Mana, PrevMana ); GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Mana, PrevMana );
} }
void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana ) void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana )
{ {
// From GAMEPLAYATTRIBUTE_REPNOTIFY // From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) ); static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(UGasaAttributeSetProperty), MaxMana, GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxMana, PrevMaxMana );
PrevMaxMana);
} }
#pragma endregion Rep Notifies #pragma endregion Rep Notifies

View File

@ -8,7 +8,6 @@ UCLASS()
class GASA_API UGasaAttributeSet : public UAttributeSet class GASA_API UGasaAttributeSet : public UAttributeSet
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
UGasaAttributeSet(); UGasaAttributeSet();
@ -36,19 +35,16 @@ public:
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) ); static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) );
return Prop; return Prop;
} }
static FGameplayAttribute GetMaxHealthAttribute() static FGameplayAttribute GetMaxHealthAttribute()
{ {
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) ); static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) );
return Prop; return Prop;
} }
static FGameplayAttribute GetManaAttribute() static FGameplayAttribute GetManaAttribute()
{ {
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) ); static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) );
return Prop; return Prop;
} }
static FGameplayAttribute GetMaxManaAttribute() static FGameplayAttribute GetMaxManaAttribute()
{ {
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) ); static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) );
@ -62,7 +58,8 @@ public:
#pragma endregion Getters #pragma endregion Getters
#pragma region Setters #pragma region Setters
FORCEINLINE void SetHealth(float NewVal); FORCEINLINE void
SetHealth( float NewVal );
FORCEINLINE void SetMaxHealth( float NewVal ); FORCEINLINE void SetMaxHealth( float NewVal );
FORCEINLINE void SetMana( float NewVal ); FORCEINLINE void SetMana( float NewVal );
FORCEINLINE void SetMaxMana( float NewVal ); FORCEINLINE void SetMaxMana( float NewVal );
@ -72,19 +69,16 @@ public:
Health.SetBaseValue( NewVal ); Health.SetBaseValue( NewVal );
Health.SetCurrentValue( NewVal ); Health.SetCurrentValue( NewVal );
} }
FORCEINLINE void InitMaxHealth( float NewVal ) FORCEINLINE void InitMaxHealth( float NewVal )
{ {
MaxHealth.SetBaseValue( NewVal ); MaxHealth.SetBaseValue( NewVal );
MaxHealth.SetCurrentValue( NewVal ); MaxHealth.SetCurrentValue( NewVal );
} }
FORCEINLINE void InitMana( float NewVal ) FORCEINLINE void InitMana( float NewVal )
{ {
Mana.SetBaseValue( NewVal ); Mana.SetBaseValue( NewVal );
Mana.SetCurrentValue( NewVal ); Mana.SetCurrentValue( NewVal );
} }
FORCEINLINE void InitMaxMana( float NewVal ) FORCEINLINE void InitMaxMana( float NewVal )
{ {
MaxMana.SetBaseValue( NewVal ); MaxMana.SetBaseValue( NewVal );
@ -93,11 +87,13 @@ public:
#pragma endregion Setters #pragma endregion Setters
#pragma region AttributeSet #pragma region AttributeSet
void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override; void
PreAttributeChange( const FGameplayAttribute& Attribute, float& NewValue ) override;
void PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data ) override; void PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data ) override;
#pragma endregion AttributeSet #pragma endregion AttributeSet
#pragma region UObject #pragma region UObject
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; void
GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override;
#pragma endregion UObject #pragma endregion UObject
}; };

View File

@ -10,6 +10,8 @@ AGasaEffectActor::AGasaEffectActor()
RootComponent = CreateDefaultSubobject<USceneComponent>("Root"); RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
Level = 1.f;
InstantEffectUsage = EInstantEffectUsagePolicy::DoNotApply; InstantEffectUsage = EInstantEffectUsagePolicy::DoNotApply;
DurationEffectUsage = DefaultEffectUsagePolicy; DurationEffectUsage = DefaultEffectUsagePolicy;
InfiniteEffectUsage = DefaultEffectUsagePolicy; InfiniteEffectUsage = DefaultEffectUsagePolicy;
@ -24,7 +26,7 @@ void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEf
Context = AS->MakeEffectContext(); Context = AS->MakeEffectContext();
Context.AddSourceObject(Actor); Context.AddSourceObject(Actor);
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context ); FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (bRemoveOnEndOverlap) if (bRemoveOnEndOverlap)
ActiveEffectsToRemove.Add(ActiveEffect, AS); ActiveEffectsToRemove.Add(ActiveEffect, AS);
@ -39,16 +41,16 @@ void AGasaEffectActor::OnOverlap(AActor* Actor)
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap) if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap)
{ {
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
} }
if (DurationEffectClass) if (DurationEffectClass)
{ {
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap)) if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap))
{ {
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, 1.0f, Context ); FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
ActiveDuration = ActiveEffect; ActiveDuration = ActiveEffect;
} }
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap)) if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
@ -59,9 +61,9 @@ void AGasaEffectActor::OnOverlap(AActor* Actor)
bool bApplyOnOverlap = Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnOverlap); bool bApplyOnOverlap = Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnOverlap);
if (bApplyOnOverlap) if (bApplyOnOverlap)
{ {
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, 1.0f, Context ); FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
ActiveInfinite = ActiveEffect; ActiveInfinite = ActiveEffect;
} }
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap)) if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
@ -81,28 +83,28 @@ void AGasaEffectActor::OnEndOverlap(AActor* Actor)
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnEndOverlap) if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnEndOverlap)
{ {
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
} }
if (DurationEffectClass) if (DurationEffectClass)
{ {
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap)) if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
{ {
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, 1.0f, Context ); FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap)) if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
ActiveDuration = ActiveEffect; ActiveDuration = ActiveEffect;
} }
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
AS->RemoveActiveGameplayEffect(ActiveDuration); AS->RemoveActiveGameplayEffect(ActiveDuration);
} }
if (InfiniteEffectClass) if (InfiniteEffectClass)
{ {
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap)) if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
{ {
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, 1.0f, Context ); FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap)) if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
ActiveInfinite = ActiveEffect; ActiveInfinite = ActiveEffect;
} }
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap)) if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))

View File

@ -35,6 +35,11 @@ class GASA_API AGasaEffectActor : public AGasaActor
GENERATED_BODY() GENERATED_BODY()
public: public:
AGasaEffectActor();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
float Level;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
TSubclassOf<UGameplayEffect> InstantEffectClass; TSubclassOf<UGameplayEffect> InstantEffectClass;
@ -62,8 +67,6 @@ public:
FActiveGameplayEffectHandle ActiveDuration; FActiveGameplayEffectHandle ActiveDuration;
FActiveGameplayEffectHandle ActiveInfinite; FActiveGameplayEffectHandle ActiveInfinite;
AGasaEffectActor();
UFUNCTION(BlueprintCallable, Category = "Gameplay Effects") UFUNCTION(BlueprintCallable, Category = "Gameplay Effects")
void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap = false); void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap = false);
@ -73,4 +76,3 @@ public:
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void OnEndOverlap(AActor* Actor); void OnEndOverlap(AActor* Actor);
}; };