25. Attribut accessors complete

There is some jank, with the ability system init on character (I'll fix later).
Cog replaces the usuals showdebug command
This commit is contained in:
Edward R. Gonzalez 2024-04-13 18:35:19 -04:00
parent 74689f6c6a
commit 99a23529e6
15 changed files with 263 additions and 30 deletions

1
.gitignore vendored
View File

@ -25,3 +25,4 @@ Project/Binaries/GasaGen.exe
Project/Binaries/GasaGen.map Project/Binaries/GasaGen.map
Project/Binaries/GasaGen.obj Project/Binaries/GasaGen.obj
Project/Binaries/vc140.pdb Project/Binaries/vc140.pdb
Project/Saved/Config/ConsoleHistory.ini

View File

@ -1,5 +1,3 @@
[/Script/EngineSettings.GeneralProjectSettings] [/Script/EngineSettings.GeneralProjectSettings]
ProjectID=70BA0A3B40E2B9899612678C078FC24A ProjectID=70BA0A3B40E2B9899612678C078FC24A
Description=GASATHON Description=GASATHON
@ -10,3 +8,5 @@ CopyrightNotice=
Tag_PPV=Global_PPV Tag_PPV=Global_PPV
Tag_GlobalPPV=Global_PPV Tag_GlobalPPV=Global_PPV
[/Script/GameplayAbilities.AbilitySystemGlobals]
bUseDebugTargetFromHud=true

View File

@ -1,3 +0,0 @@
[ConsoleHistory]
History=Cog.ToggleInput

View File

@ -8,7 +8,7 @@
#include "GasaAbilitySystemComponent.generated.h" #include "GasaAbilitySystemComponent.generated.h"
UCLASS() UCLASS(BlueprintType)
class GASA_API UGasaAbilitySystemComp : public UAbilitySystemComponent class GASA_API UGasaAbilitySystemComp : public UAbilitySystemComponent
{ {
GENERATED_BODY() GENERATED_BODY()

View File

@ -7,6 +7,10 @@
UGasaAttributeSet::UGasaAttributeSet() UGasaAttributeSet::UGasaAttributeSet()
{ {
InitHealth( 100.f );
InitMaxHealth( 100.f );
InitMana( ( 50.f ) );
InitMaxMana( 50.f );
} }
void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth ) void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth )

View File

@ -1,7 +1,7 @@
// This was generated by GasaGen/GasaGen.cpp // This was generated by GasaGen/GasaGen.cpp
#include "AttributeSet.h" #include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "GasaAttributeSet.generated.h" #include "GasaAttributeSet.generated.h"
UCLASS() class GASA_API UGasaAttributeSet : public UAttributeSet UCLASS() class GASA_API UGasaAttributeSet : public UAttributeSet
@ -11,13 +11,13 @@ public:
UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Health; FGameplayAttributeData Health;
UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData MaxHealth; FGameplayAttributeData MaxHealth;
UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) UPROPERTY( ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Mana; FGameplayAttributeData Mana;
UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData MaxMana; FGameplayAttributeData MaxMana;
UGasaAttributeSet(); UGasaAttributeSet();
@ -31,6 +31,117 @@ public:
UFUNCTION() 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 ) );
return Prop;
}
static FGameplayAttribute GetMaxHealthAttribute()
{
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 ) );
return Prop;
}
static FGameplayAttribute GetMaxManaAttribute()
{
static FProperty* Prop = FindFieldChecked< FProperty >( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) );
return Prop;
}
FORCEINLINE float GetHealth() const
{
return Health.GetCurrentValue();
}
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 region Setters
FORCEINLINE void SetHealth( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetHealthAttribute(), NewVal );
};
}
FORCEINLINE void SetMaxHealth( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetMaxHealthAttribute(), NewVal );
};
}
FORCEINLINE void SetMana( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetManaAttribute(), NewVal );
};
}
FORCEINLINE void SetMaxMana( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetMaxManaAttribute(), NewVal );
};
}
FORCEINLINE void InitHealth( float NewVal )
{
Health.SetBaseValue( NewVal );
Health.SetCurrentValue( NewVal );
}
FORCEINLINE void InitMaxHealth( float NewVal )
{
MaxHealth.SetBaseValue( NewVal );
MaxHealth.SetCurrentValue( NewVal );
}
FORCEINLINE void InitMana( float NewVal )
{
Mana.SetBaseValue( NewVal );
Mana.SetCurrentValue( NewVal );
}
FORCEINLINE void InitMaxMana( float NewVal )
{
MaxMana.SetBaseValue( NewVal );
MaxMana.SetCurrentValue( NewVal );
}
#pragma endregion Setters
#pragma region UObject #pragma region UObject
void GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const override; void GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const override;

View File

@ -3,4 +3,6 @@
AEnemyCharacter::AEnemyCharacter() AEnemyCharacter::AEnemyCharacter()
{ {
PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bCanEverTick = true;
bAutoAbilitySystem = true;
} }

View File

@ -8,6 +8,7 @@
#include "Kismet/KismetSystemLibrary.h" #include "Kismet/KismetSystemLibrary.h"
#include "AbilitySystem/GasaAbilitySystemComponent.h" #include "AbilitySystem/GasaAbilitySystemComponent.h"
#include "AbilitySystem/GasaAttributeSet.h"
#include "Game/GasaLevelScriptActor.h" #include "Game/GasaLevelScriptActor.h"
void AGasaCharacter::SetHighlight(EHighlight Desired) void AGasaCharacter::SetHighlight(EHighlight Desired)
@ -45,7 +46,7 @@ AGasaCharacter::AGasaCharacter()
AbilitySystem->SetIsReplicated(true); AbilitySystem->SetIsReplicated(true);
AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Minimal); AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);
Attributes = CreateDefaultSubobject<UAttributeSet>("Attributes"); Attributes = CreateDefaultSubobject<UGasaAttributeSet>("Attributes");
} }
} }
@ -71,6 +72,12 @@ void AGasaCharacter::OnRep_PlayerState()
void AGasaCharacter::BeginPlay() void AGasaCharacter::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
if (bAutoAbilitySystem)
{
// TODO(Ed): Do we need to do this for enemies?
AbilitySystem->InitAbilityActorInfo(this, this);
}
} }
void AGasaCharacter::Tick(float DeltaSeconds) void AGasaCharacter::Tick(float DeltaSeconds)

View File

@ -9,6 +9,19 @@ APlayerCharacter::APlayerCharacter()
bAutoAbilitySystem = false; bAutoAbilitySystem = false;
} }
void APlayerCharacter::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
AGasaPlayerState* PS = GetGasaPlayerState();
// Server setup ability system (character side)
{
AbilitySystem = PS->AbilitySystem;
Attributes = PS->Attributes;
AbilitySystem->InitAbilityActorInfo(PS, this);
}
}
void APlayerCharacter::OnRep_PlayerState() void APlayerCharacter::OnRep_PlayerState()
{ {
Super::OnRep_PlayerState(); Super::OnRep_PlayerState();

View File

@ -13,6 +13,8 @@ public:
APlayerCharacter(); APlayerCharacter();
#pragma region Pawn #pragma region Pawn
void PossessedBy(AController* NewController) override;
void OnRep_PlayerState() override; void OnRep_PlayerState() override;
#pragma endregion Pawn #pragma endregion Pawn
}; };

View File

@ -73,6 +73,7 @@ void AGasaPlayerController::OnPossess(APawn* InPawn)
AGasaPlayerState* PS = GetPlayerState(); AGasaPlayerState* PS = GetPlayerState();
AGasaCharacter* character = Cast<AGasaCharacter>(InPawn); AGasaCharacter* character = Cast<AGasaCharacter>(InPawn);
// Net Owner setup ability system // Net Owner setup ability system
if (0)
{ {
character->AbilitySystem = PS->AbilitySystem; character->AbilitySystem = PS->AbilitySystem;
character->Attributes = PS->Attributes; character->Attributes = PS->Attributes;

View File

@ -1,6 +1,7 @@
#include "GasaPlayerState.h" #include "GasaPlayerState.h"
#include "AbilitySystem/GasaAbilitySystemComponent.h" #include "AbilitySystem/GasaAbilitySystemComponent.h"
#include "AbilitySystem/GasaAttributeSet.h"
AGasaPlayerState::AGasaPlayerState() AGasaPlayerState::AGasaPlayerState()
{ {
@ -8,7 +9,7 @@ AGasaPlayerState::AGasaPlayerState()
AbilitySystem->SetIsReplicated(true); AbilitySystem->SetIsReplicated(true);
AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Mixed); AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
Attributes = CreateDefaultSubobject<UAttributeSet>("Attributes"); Attributes = CreateDefaultSubobject<UGasaAttributeSet>("Attributes");
// Replication // Replication
NetUpdateFrequency = 100.f; NetUpdateFrequency = 100.f;

View File

@ -13,26 +13,26 @@ using namespace gen;
#define path_gasa_ability_system path_module_gasa "AbilitySystem/" #define path_gasa_ability_system path_module_gasa "AbilitySystem/"
void def_attribute_fields( CodeBody body, Array<StringCached> fields ) void def_attribute_properties( CodeBody body, Array<StringCached> properties )
{ {
for ( String field : fields ) for ( StringCached property : properties )
{ {
Code field_uproperty = code_str( Code field_uproperty = code_fmt( "property", (StrC)property, stringize(
UPROPERTY(ReplicatedUsing=Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category="Attributes") UPROPERTY(ReplicatedUsing=Client_OnRep_<property>, EditAnywhere, BlueprintReadWrite, Category="Attributes")
); ));
CodeType type_FGameplayAttributeData = def_type( txt("FGameplayAttributeData")); CodeType type_FGameplayAttributeData = def_type( txt("FGameplayAttributeData"));
body.append(fmt_newline); body.append(fmt_newline);
body.append( field_uproperty ); body.append( field_uproperty );
body.append(fmt_newline); body.append(fmt_newline);
body.append( def_variable( type_FGameplayAttributeData, StrC(field)) ); body.append( def_variable( type_FGameplayAttributeData, StrC(property)) );
} }
} }
void def_attribute_field_on_reps( CodeBody body, Array<StringCached> fields ) void def_attribute_field_on_reps( CodeBody body, Array<StringCached> fields )
{ {
for ( String field : fields ) for ( StringCached field : fields )
{ {
Code umeta_UFUNCTION = code_str( UFUNCTION() ); Code umeta_UFUNCTION = code_str( UFUNCTION() );
@ -45,17 +45,89 @@ void def_attribute_field_on_reps( CodeBody body, Array<StringCached> fields )
} }
} }
void impl_attribute_fields( CodeBody body, Array<StringCached> fields ) void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array<StringCached> properties )
{ {
for ( String field : fields ) for ( String property : properties )
{ {
body.append(fmt_newline); CodeFn generated_get_attribute = parse_function(
CodeFn field_impl = parse_function( token_fmt( "field", (StrC)field, stringize( token_fmt( "class_name", class_name, "property", (StrC)property,
void UGasaAttributeSet::Client_OnRep_<field>(FGameplayAttributeData& Prev<field>) stringize(
static FGameplayAttribute Get<property>Attribute()
{
static FProperty* Prop = FindFieldChecked<FProperty>(<class_name>::StaticClass(), GET_MEMBER_NAME_CHECKED(<class_name>, <property>));
return Prop;
}
)));
body.append( generated_get_attribute );
}
}
void def_attribute_field_value_getters( CodeBody body, Array<StringCached> properties )
{
for ( String property : properties )
{
#pragma push_macro(FORCEINLINE)
#undef FORCEINLINE
body.append( code_fmt( "property", (StrC)property,
stringize(
FORCEINLINE float Get<property>() const
{ {
GAMEPLAYATTRIBUTE_REPNOTIFY(UGasaAttributeSet, <field>, Prev<field>) return <property>.GetCurrentValue();
} }
))); )));
#pragma pop_macro(FORCEINLINE)
}
}
void def_attribute_field_value_setters( CodeBody body, Array<StringCached> properties )
{
for ( String property : properties )
{
body.append( code_fmt( "property", (StrC)property,
stringize(
FORCEINLINE void Set<property>(float NewVal)
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if (ensure(AbilityComp))
{
AbilityComp->SetNumericAttributeBase(Get<property>Attribute(), NewVal);
};
}
)));
}
}
void def_attribute_field_initers ( CodeBody body, Array<StringCached> properties )
{
for ( String property : properties )
{
body.append( code_fmt( "property", (StrC)property,
stringize(
FORCEINLINE void Init<property>(float NewVal)
{
<property>.SetBaseValue(NewVal);
<property>.SetCurrentValue(NewVal);
}
)));
}
}
void impl_attribute_fields( CodeBody body, StrC class_name, Array<StringCached> properties )
{
for ( String property : properties )
{
body.append(fmt_newline);
CodeFn field_impl = parse_function( token_fmt( "class_name", class_name, "property", (StrC)property,
stringize(
void <class_name>::Client_OnRep_<property>(FGameplayAttributeData& Prev<property>)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(<class_name>, <property>, Prev<property>)
}
)));
body.append( field_impl ); body.append( field_impl );
} }
} }
@ -79,12 +151,16 @@ int gen_main()
attribute_fields.append( get_cached_string(txt("Mana"))); attribute_fields.append( get_cached_string(txt("Mana")));
attribute_fields.append( get_cached_string(txt("MaxMana"))); attribute_fields.append( get_cached_string(txt("MaxMana")));
StrC attributeset_name = txt("UGasaAttributeSet");
Builder header = Builder::open( path_gasa_ability_system "GasaAttributeSet.h"); Builder header = Builder::open( path_gasa_ability_system "GasaAttributeSet.h");
{ {
header.print(generation_notice); header.print(generation_notice);
header.print(fmt_newline); header.print(fmt_newline);
{ {
CodeInclude Include_AttributeSet = def_include(txt("AttributeSet.h")); CodeInclude Include_AttributeSet = def_include(txt("AttributeSet.h"));
CodeInclude Include_AbilitySystemComponent = def_include(txt("AbilitySystemComponent.h"));
CodeInclude Include_GasaAttributeSet_Generated = def_include(txt("GasaAttributeSet.generated.h")); CodeInclude Include_GasaAttributeSet_Generated = def_include(txt("GasaAttributeSet.generated.h"));
CodeAttributes attributes = def_attributes( gasa_api->Name); CodeAttributes attributes = def_attributes( gasa_api->Name);
@ -97,7 +173,7 @@ int gen_main()
body.append( fmt_newline); body.append( fmt_newline);
body.append( access_public ); body.append( access_public );
def_attribute_fields( body, attribute_fields); def_attribute_properties( body, attribute_fields);
body.append(fmt_newline); body.append(fmt_newline);
body.append( def_constructor() ); body.append( def_constructor() );
@ -105,7 +181,19 @@ int gen_main()
def_attribute_field_on_reps( body, attribute_fields); def_attribute_field_on_reps( body, attribute_fields);
body.append(fmt_newline); body.append(fmt_newline);
body.append(fmt_newline);
body.append( fmt_newline );
body.append( def_pragma(code( region Getters )));
def_attribute_field_property_getters( body, attributeset_name, attribute_fields );
def_attribute_field_value_getters( body, attribute_fields );
body.append( def_pragma(code( endregion Getters )));
body.append( fmt_newline );
body.append( def_pragma(code( region Setters )));
def_attribute_field_value_setters( body, attribute_fields );
def_attribute_field_initers( body, attribute_fields );
body.append( def_pragma(code( endregion Setters )));
body.append( fmt_newline );
body.append( def_pragma( txt("region UObject"))); body.append( def_pragma( txt("region UObject")));
body.append( parse_function( code( body.append( parse_function( code(
@ -121,7 +209,7 @@ int gen_main()
} }
header.print( Include_AttributeSet); header.print( Include_AttributeSet);
header.print( fmt_newline); header.print( Include_AbilitySystemComponent);
header.print( Include_GasaAttributeSet_Generated); header.print( Include_GasaAttributeSet_Generated);
header.print( fmt_newline); header.print( fmt_newline);
header.print(umeta_uclass); header.print(umeta_uclass);
@ -142,11 +230,17 @@ int gen_main()
CodeBody body = def_body( CodeT::Global_Body ); CodeBody body = def_body( CodeT::Global_Body );
body.append(fmt_newline); body.append(fmt_newline);
body.append(code_str( body.append(code_str(
UGasaAttributeSet::UGasaAttributeSet() {} UGasaAttributeSet::UGasaAttributeSet()
{
InitHealth( 100.f );
InitMaxHealth( 100.f );
InitMana(( 50.f ));
InitMaxMana( 50.f );
}
)); ));
body.append(fmt_newline); body.append(fmt_newline);
impl_attribute_fields(body, attribute_fields); impl_attribute_fields( body, attributeset_name, attribute_fields);
CodeFn GetLifetimeOfReplicatedProps; CodeFn GetLifetimeOfReplicatedProps;
{ {