diff --git a/.gitignore b/.gitignore index 7fa14d8..41e05ad 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ Project/Binaries/GasaGen.exe Project/Binaries/GasaGen.map Project/Binaries/GasaGen.obj Project/Binaries/vc140.pdb +Project/Saved/Config/ConsoleHistory.ini diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.dll b/Project/Binaries/Win64/UnrealEditor-Gasa.dll index aab7b6f..73bbc9d 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-Gasa.dll and b/Project/Binaries/Win64/UnrealEditor-Gasa.dll differ diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb index e401daa..96157e8 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb and b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb differ diff --git a/Project/Config/DefaultGame.ini b/Project/Config/DefaultGame.ini index 4e58ee5..0625065 100644 --- a/Project/Config/DefaultGame.ini +++ b/Project/Config/DefaultGame.ini @@ -1,5 +1,3 @@ - - [/Script/EngineSettings.GeneralProjectSettings] ProjectID=70BA0A3B40E2B9899612678C078FC24A Description=GASATHON @@ -10,3 +8,5 @@ CopyrightNotice= Tag_PPV=Global_PPV Tag_GlobalPPV=Global_PPV +[/Script/GameplayAbilities.AbilitySystemGlobals] +bUseDebugTargetFromHud=true diff --git a/Project/Content/Levels/StartupMap.umap b/Project/Content/Levels/StartupMap.umap index 01bfa8d..2ea3bf3 100644 --- a/Project/Content/Levels/StartupMap.umap +++ b/Project/Content/Levels/StartupMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6edae47c3b150aaff52d88c10bbcc4087ece41ab5dbaea253f69a5fea75fc87 -size 69125 +oid sha256:ba40738eafa6ae9f406b8e60332786e112fd4ec8d42ac718f067ddaba014fcef +size 70653 diff --git a/Project/Saved/Config/ConsoleHistory.ini b/Project/Saved/Config/ConsoleHistory.ini deleted file mode 100644 index e6d7a75..0000000 --- a/Project/Saved/Config/ConsoleHistory.ini +++ /dev/null @@ -1,3 +0,0 @@ -[ConsoleHistory] -History=Cog.ToggleInput - diff --git a/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent.h b/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent.h index bca2a46..4d91ba0 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent.h +++ b/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent.h @@ -8,7 +8,7 @@ #include "GasaAbilitySystemComponent.generated.h" -UCLASS() +UCLASS(BlueprintType) class GASA_API UGasaAbilitySystemComp : public UAbilitySystemComponent { GENERATED_BODY() diff --git a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp index de39c96..832f52d 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp +++ b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp @@ -7,6 +7,10 @@ UGasaAttributeSet::UGasaAttributeSet() { + InitHealth( 100.f ); + InitMaxHealth( 100.f ); + InitMana( ( 50.f ) ); + InitMaxMana( 50.f ); } void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth ) diff --git a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h index c765046..7c8ad02 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h +++ b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.h @@ -1,7 +1,7 @@ // This was generated by GasaGen/GasaGen.cpp #include "AttributeSet.h" - +#include "AbilitySystemComponent.h" #include "GasaAttributeSet.generated.h" UCLASS() class GASA_API UGasaAttributeSet : public UAttributeSet @@ -11,13 +11,13 @@ public: UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) FGameplayAttributeData Health; - UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) + UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) FGameplayAttributeData MaxHealth; - UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) + UPROPERTY( ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) FGameplayAttributeData Mana; - UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) + UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) FGameplayAttributeData MaxMana; UGasaAttributeSet(); @@ -31,6 +31,117 @@ public: UFUNCTION() 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 void GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const override; diff --git a/Project/Source/Gasa/Characters/EnemyCharacter.cpp b/Project/Source/Gasa/Characters/EnemyCharacter.cpp index b07f232..fad9c7a 100644 --- a/Project/Source/Gasa/Characters/EnemyCharacter.cpp +++ b/Project/Source/Gasa/Characters/EnemyCharacter.cpp @@ -3,4 +3,6 @@ AEnemyCharacter::AEnemyCharacter() { PrimaryActorTick.bCanEverTick = true; + + bAutoAbilitySystem = true; } diff --git a/Project/Source/Gasa/Characters/GasaCharacter.cpp b/Project/Source/Gasa/Characters/GasaCharacter.cpp index f02ddf6..d224f81 100644 --- a/Project/Source/Gasa/Characters/GasaCharacter.cpp +++ b/Project/Source/Gasa/Characters/GasaCharacter.cpp @@ -8,6 +8,7 @@ #include "Kismet/KismetSystemLibrary.h" #include "AbilitySystem/GasaAbilitySystemComponent.h" +#include "AbilitySystem/GasaAttributeSet.h" #include "Game/GasaLevelScriptActor.h" void AGasaCharacter::SetHighlight(EHighlight Desired) @@ -45,7 +46,7 @@ AGasaCharacter::AGasaCharacter() AbilitySystem->SetIsReplicated(true); AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Minimal); - Attributes = CreateDefaultSubobject("Attributes"); + Attributes = CreateDefaultSubobject("Attributes"); } } @@ -71,6 +72,12 @@ void AGasaCharacter::OnRep_PlayerState() void AGasaCharacter::BeginPlay() { Super::BeginPlay(); + + if (bAutoAbilitySystem) + { + // TODO(Ed): Do we need to do this for enemies? + AbilitySystem->InitAbilityActorInfo(this, this); + } } void AGasaCharacter::Tick(float DeltaSeconds) diff --git a/Project/Source/Gasa/Characters/PlayerCharacter.cpp b/Project/Source/Gasa/Characters/PlayerCharacter.cpp index 84a393b..849cbf8 100644 --- a/Project/Source/Gasa/Characters/PlayerCharacter.cpp +++ b/Project/Source/Gasa/Characters/PlayerCharacter.cpp @@ -9,6 +9,19 @@ APlayerCharacter::APlayerCharacter() 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() { Super::OnRep_PlayerState(); diff --git a/Project/Source/Gasa/Characters/PlayerCharacter.h b/Project/Source/Gasa/Characters/PlayerCharacter.h index 6b99be5..984a79d 100644 --- a/Project/Source/Gasa/Characters/PlayerCharacter.h +++ b/Project/Source/Gasa/Characters/PlayerCharacter.h @@ -13,6 +13,8 @@ public: APlayerCharacter(); #pragma region Pawn + void PossessedBy(AController* NewController) override; + void OnRep_PlayerState() override; #pragma endregion Pawn }; diff --git a/Project/Source/Gasa/Game/GasaPlayerController.cpp b/Project/Source/Gasa/Game/GasaPlayerController.cpp index 4f5c1d5..09c1090 100644 --- a/Project/Source/Gasa/Game/GasaPlayerController.cpp +++ b/Project/Source/Gasa/Game/GasaPlayerController.cpp @@ -73,6 +73,7 @@ void AGasaPlayerController::OnPossess(APawn* InPawn) AGasaPlayerState* PS = GetPlayerState(); AGasaCharacter* character = Cast(InPawn); // Net Owner setup ability system + if (0) { character->AbilitySystem = PS->AbilitySystem; character->Attributes = PS->Attributes; diff --git a/Project/Source/Gasa/Game/GasaPlayerState.cpp b/Project/Source/Gasa/Game/GasaPlayerState.cpp index a862ca7..69d6747 100644 --- a/Project/Source/Gasa/Game/GasaPlayerState.cpp +++ b/Project/Source/Gasa/Game/GasaPlayerState.cpp @@ -1,6 +1,7 @@ #include "GasaPlayerState.h" #include "AbilitySystem/GasaAbilitySystemComponent.h" +#include "AbilitySystem/GasaAttributeSet.h" AGasaPlayerState::AGasaPlayerState() { @@ -8,7 +9,7 @@ AGasaPlayerState::AGasaPlayerState() AbilitySystem->SetIsReplicated(true); AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Mixed); - Attributes = CreateDefaultSubobject("Attributes"); + Attributes = CreateDefaultSubobject("Attributes"); // Replication NetUpdateFrequency = 100.f; diff --git a/Project/Source/GasaGen/GasaGen.cpp b/Project/Source/GasaGen/GasaGen.cpp index 859b26b..1af3241 100644 --- a/Project/Source/GasaGen/GasaGen.cpp +++ b/Project/Source/GasaGen/GasaGen.cpp @@ -13,26 +13,26 @@ using namespace gen; #define path_gasa_ability_system path_module_gasa "AbilitySystem/" -void def_attribute_fields( CodeBody body, Array fields ) +void def_attribute_properties( CodeBody body, Array properties ) { - for ( String field : fields ) + for ( StringCached property : properties ) { - Code field_uproperty = code_str( - UPROPERTY(ReplicatedUsing=Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category="Attributes") - ); + Code field_uproperty = code_fmt( "property", (StrC)property, stringize( + UPROPERTY(ReplicatedUsing=Client_OnRep_, EditAnywhere, BlueprintReadWrite, Category="Attributes") + )); CodeType type_FGameplayAttributeData = def_type( txt("FGameplayAttributeData")); body.append(fmt_newline); body.append( field_uproperty ); 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 fields ) { - for ( String field : fields ) + for ( StringCached field : fields ) { Code umeta_UFUNCTION = code_str( UFUNCTION() ); @@ -45,17 +45,89 @@ void def_attribute_field_on_reps( CodeBody body, Array fields ) } } -void impl_attribute_fields( CodeBody body, Array fields ) +void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array properties ) { - for ( String field : fields ) + for ( String property : properties ) { - body.append(fmt_newline); - CodeFn field_impl = parse_function( token_fmt( "field", (StrC)field, stringize( - void UGasaAttributeSet::Client_OnRep_(FGameplayAttributeData& Prev) + CodeFn generated_get_attribute = parse_function( + token_fmt( "class_name", class_name, "property", (StrC)property, + stringize( + static FGameplayAttribute GetAttribute() + { + static FProperty* Prop = FindFieldChecked(::StaticClass(), GET_MEMBER_NAME_CHECKED(, )); + return Prop; + } + ))); + body.append( generated_get_attribute ); + } +} + +void def_attribute_field_value_getters( CodeBody body, Array properties ) +{ + for ( String property : properties ) + { + #pragma push_macro(FORCEINLINE) + #undef FORCEINLINE + + body.append( code_fmt( "property", (StrC)property, + stringize( + FORCEINLINE float Get() const { - GAMEPLAYATTRIBUTE_REPNOTIFY(UGasaAttributeSet, , Prev) + return .GetCurrentValue(); } ))); + + #pragma pop_macro(FORCEINLINE) + } +} + +void def_attribute_field_value_setters( CodeBody body, Array properties ) +{ + for ( String property : properties ) + { + body.append( code_fmt( "property", (StrC)property, + stringize( + FORCEINLINE void Set(float NewVal) + { + UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent(); + if (ensure(AbilityComp)) + { + AbilityComp->SetNumericAttributeBase(GetAttribute(), NewVal); + }; + } + ))); + } +} + +void def_attribute_field_initers ( CodeBody body, Array properties ) +{ + for ( String property : properties ) + { + body.append( code_fmt( "property", (StrC)property, + stringize( + FORCEINLINE void Init(float NewVal) + { + .SetBaseValue(NewVal); + .SetCurrentValue(NewVal); + } + ))); + } +} + +void impl_attribute_fields( CodeBody body, StrC class_name, Array 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 ::Client_OnRep_(FGameplayAttributeData& Prev) + { + GAMEPLAYATTRIBUTE_REPNOTIFY(, , Prev) + } + ))); + 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("MaxMana"))); + + StrC attributeset_name = txt("UGasaAttributeSet"); + Builder header = Builder::open( path_gasa_ability_system "GasaAttributeSet.h"); { header.print(generation_notice); header.print(fmt_newline); { 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")); CodeAttributes attributes = def_attributes( gasa_api->Name); @@ -97,7 +173,7 @@ int gen_main() body.append( fmt_newline); body.append( access_public ); - def_attribute_fields( body, attribute_fields); + def_attribute_properties( body, attribute_fields); body.append(fmt_newline); body.append( def_constructor() ); @@ -105,7 +181,19 @@ int gen_main() def_attribute_field_on_reps( body, attribute_fields); 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( parse_function( code( @@ -121,7 +209,7 @@ int gen_main() } header.print( Include_AttributeSet); - header.print( fmt_newline); + header.print( Include_AbilitySystemComponent); header.print( Include_GasaAttributeSet_Generated); header.print( fmt_newline); header.print(umeta_uclass); @@ -142,11 +230,17 @@ int gen_main() CodeBody body = def_body( CodeT::Global_Body ); body.append(fmt_newline); body.append(code_str( - UGasaAttributeSet::UGasaAttributeSet() {} + UGasaAttributeSet::UGasaAttributeSet() + { + InitHealth( 100.f ); + InitMaxHealth( 100.f ); + InitMana(( 50.f )); + InitMaxMana( 50.f ); + } )); body.append(fmt_newline); - impl_attribute_fields(body, attribute_fields); + impl_attribute_fields( body, attributeset_name, attribute_fields); CodeFn GetLifetimeOfReplicatedProps; {