53. Gameplay Effect Delegates

This commit is contained in:
Edward R. Gonzalez 2024-04-25 00:30:54 -04:00
parent ae1e28a072
commit 33b3723b82
16 changed files with 129 additions and 117 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="")

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Project/Content/Core/BP_AreaFire.uasset (Stored with Git LFS)

Binary file not shown.

BIN
Project/Content/Core/CT_Potion.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/Core/DT_PrimaryAttributes.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Project/Content/Levels/StartupMap.umap (Stored with Git LFS)

Binary file not shown.

View File

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

View File

@ -9,79 +9,74 @@
UGasaAttributeSet::UGasaAttributeSet()
{
InitHealth(100.f);
InitMaxHealth(100.f);
InitMana(50.f);
InitMaxMana(50.f);
InitHealth( 100.f );
InitMaxHealth( 100.f );
InitMana( 50.f );
InitMaxMana( 50.f );
}
#pragma region Rep Notifies
void UGasaAttributeSet::Client_OnRep_Health(FGameplayAttributeData& PrevHealth)
void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>(StaticClass(), GET_MEMBER_NAME_CHECKED(UGasaAttributeSet, Health));
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(UGasaAttributeSetProperty), Health, PrevHealth);
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Health, PrevHealth );
}
void UGasaAttributeSet::Client_OnRep_MaxHealth(FGameplayAttributeData& PrevMaxHealth)
void UGasaAttributeSet::Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>(StaticClass(), GET_MEMBER_NAME_CHECKED(UGasaAttributeSet, MaxHealth));
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(UGasaAttributeSetProperty), MaxHealth,
PrevMaxHealth);
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxHealth, PrevMaxHealth );
}
void UGasaAttributeSet::Client_OnRep_Mana(FGameplayAttributeData& PrevMana)
void UGasaAttributeSet::Client_OnRep_Mana( FGameplayAttributeData& PrevMana )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>(StaticClass(), GET_MEMBER_NAME_CHECKED(UGasaAttributeSet, Mana));
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(UGasaAttributeSetProperty), Mana, PrevMana);
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Mana, PrevMana );
}
void UGasaAttributeSet::Client_OnRep_MaxMana(FGameplayAttributeData& PrevMaxMana)
void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>(StaticClass(), GET_MEMBER_NAME_CHECKED(UGasaAttributeSet, MaxMana));
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(UGasaAttributeSetProperty), MaxMana,
PrevMaxMana);
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxMana, PrevMaxMana );
}
#pragma endregion Rep Notifies
void UGasaAttributeSet::PostGameplayEffectExecute(FGameplayEffectModCallbackData const& Data)
void UGasaAttributeSet::PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data )
{
Super::PostGameplayEffectExecute(Data);
Super::PostGameplayEffectExecute( Data );
FEffectProperties Props;
Props.Populate(Data);
Props.Populate( Data );
}
void UGasaAttributeSet::PreAttributeChange(FGameplayAttribute const& Attribute, float& NewValue)
void UGasaAttributeSet::PreAttributeChange( FGameplayAttribute const& Attribute, float& NewValue )
{
Super::PreAttributeChange(Attribute, NewValue);
Super::PreAttributeChange( Attribute, NewValue );
if (Attribute == GetHealthAttribute())
if ( Attribute == GetHealthAttribute() )
{
NewValue = FMath::Clamp(NewValue, 0, GetMaxHealth());
NewValue = FMath::Clamp( NewValue, 0, GetMaxHealth() );
}
if (Attribute == GetMaxHealthAttribute())
if ( Attribute == GetMaxHealthAttribute() )
{
NewValue = FMath::Clamp(NewValue, 0, 99999.000000);
NewValue = FMath::Clamp( NewValue, 0, 99999.000000 );
}
if (Attribute == GetManaAttribute())
if ( Attribute == GetManaAttribute() )
{
NewValue = FMath::Clamp(NewValue, 0, GetMaxMana());
NewValue = FMath::Clamp( NewValue, 0, GetMaxMana() );
}
if (Attribute == GetMaxManaAttribute())
if ( Attribute == GetMaxManaAttribute() )
{
NewValue = FMath::Clamp(NewValue, 0, 99999.000000);
NewValue = FMath::Clamp( NewValue, 0, 99999.000000 );
}
}
void UGasaAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
Super::GetLifetimeReplicatedProps( OutLifetimeProps );
DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, Health);
DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, MaxHealth);
DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, Mana);
DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, MaxMana);
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Health );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, MaxHealth );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Mana );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, MaxMana );
}

View File

@ -8,50 +8,46 @@ UCLASS()
class GASA_API UGasaAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UGasaAttributeSet();
UPROPERTY(ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes")
UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Health;
UPROPERTY(ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes")
UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData MaxHealth;
UPROPERTY(ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes")
UPROPERTY( ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Mana;
UPROPERTY(ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes")
UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData MaxMana;
UFUNCTION()
void Client_OnRep_Health(FGameplayAttributeData& PrevHealth);
void Client_OnRep_Health( FGameplayAttributeData& PrevHealth );
UFUNCTION()
void Client_OnRep_MaxHealth(FGameplayAttributeData& PrevMaxHealth);
void Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth );
UFUNCTION()
void Client_OnRep_Mana(FGameplayAttributeData& PrevMana);
void Client_OnRep_Mana( FGameplayAttributeData& PrevMana );
UFUNCTION()
void Client_OnRep_MaxMana(FGameplayAttributeData& PrevMaxMana);
void Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana );
#pragma region Getters
static FGameplayAttribute GetHealthAttribute()
{
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;
}
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;
}
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;
}
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 ) );
return Prop;
}
@ -59,45 +55,45 @@ public:
FORCEINLINE float GetMaxHealth() const { return MaxHealth.GetCurrentValue(); }
FORCEINLINE float GetMana() const { return Mana.GetCurrentValue(); }
FORCEINLINE float GetMaxMana() const { return MaxMana.GetCurrentValue(); }
#pragma endregion Getters
#pragma endregion Getters
#pragma region Setters
FORCEINLINE void SetHealth(float NewVal);
FORCEINLINE void SetMaxHealth(float NewVal);
FORCEINLINE void SetMana(float NewVal);
FORCEINLINE void SetMaxMana(float NewVal);
FORCEINLINE void
SetHealth( float NewVal );
FORCEINLINE void SetMaxHealth( float NewVal );
FORCEINLINE void SetMana( float NewVal );
FORCEINLINE void SetMaxMana( float NewVal );
FORCEINLINE void InitHealth(float NewVal)
FORCEINLINE void InitHealth( float NewVal )
{
Health.SetBaseValue(NewVal);
Health.SetCurrentValue(NewVal);
Health.SetBaseValue( NewVal );
Health.SetCurrentValue( NewVal );
}
FORCEINLINE void InitMaxHealth(float NewVal)
FORCEINLINE void InitMaxHealth( float NewVal )
{
MaxHealth.SetBaseValue(NewVal);
MaxHealth.SetCurrentValue(NewVal);
MaxHealth.SetBaseValue( NewVal );
MaxHealth.SetCurrentValue( NewVal );
}
FORCEINLINE void InitMana(float NewVal)
FORCEINLINE void InitMana( float NewVal )
{
Mana.SetBaseValue(NewVal);
Mana.SetCurrentValue(NewVal);
Mana.SetBaseValue( NewVal );
Mana.SetCurrentValue( NewVal );
}
FORCEINLINE void InitMaxMana(float NewVal)
FORCEINLINE void InitMaxMana( float NewVal )
{
MaxMana.SetBaseValue(NewVal);
MaxMana.SetCurrentValue(NewVal);
MaxMana.SetBaseValue( NewVal );
MaxMana.SetCurrentValue( NewVal );
}
#pragma endregion Setters
#pragma endregion Setters
#pragma region AttributeSet
void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
void PostGameplayEffectExecute(FGameplayEffectModCallbackData const& Data) override;
#pragma endregion AttributeSet
void
PreAttributeChange( const FGameplayAttribute& Attribute, float& NewValue ) override;
void PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data ) override;
#pragma endregion AttributeSet
#pragma region UObject
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
void
GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override;
#pragma endregion UObject
};

View File

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

View File

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