Compare commits

..

2 Commits

Author SHA1 Message Date
Ed_
2522f4df6c Starting to figure out attribute set more (Part of 65. 65. Initialize Attributes from a Data Table)
Going to move gasagen code to editor module.
2024-10-21 16:10:56 -04:00
Ed_
067c2f03c5 64. Properly Clamping Attributes 2024-10-19 22:34:51 -04:00
11 changed files with 398 additions and 52 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<N10X> <N10X>
<Workspace> <Workspace>
<IncludeFilter>*.*</IncludeFilter> <IncludeFilter>*.*,</IncludeFilter>
<ExcludeFilter>*.obj,*.lib,*.pch,*.dll,*.pdb,.vs,Debug,Release,x64,obj,*.user,Intermediate</ExcludeFilter> <ExcludeFilter>*.obj,*.lib,*.pch,*.dll,*.pdb,.vs,Debug,Release,x64,obj,*.user,Intermediate,</ExcludeFilter>
<SyncFiles>true</SyncFiles> <SyncFiles>true</SyncFiles>
<Recursive>true</Recursive> <Recursive>true</Recursive>
<ShowEmptyFolders>true</ShowEmptyFolders> <ShowEmptyFolders>true</ShowEmptyFolders>
@ -15,12 +15,13 @@
<CleanCommand></CleanCommand> <CleanCommand></CleanCommand>
<BuildWorkingDirectory></BuildWorkingDirectory> <BuildWorkingDirectory></BuildWorkingDirectory>
<CancelBuild></CancelBuild> <CancelBuild></CancelBuild>
<RunCommand></RunCommand> <Exe></Exe>
<RunCommandWorkingDirectory></RunCommandWorkingDirectory> <Args></Args>
<WorkingDirectory></WorkingDirectory>
<DebugCommand></DebugCommand> <DebugCommand></DebugCommand>
<ExePathCommand></ExePathCommand>
<DebugSln></DebugSln> <DebugSln></DebugSln>
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat> <UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
<CaptureExeOutput>false</CaptureExeOutput>
<Configurations> <Configurations>
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
@ -39,8 +40,24 @@
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt</AdditionalIncludePath> <AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath> <AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath>
</AdditionalIncludePaths> </AdditionalIncludePaths>
<Defines></Defines> <Defines>
<ConfigProperties></ConfigProperties> <Define>GASA_INTELLISENSE_DIRECTIVES</Define>
</Defines>
<ConfigProperties>
<ConfigAndPlatform>
<Name>Debug:x64</Name>
<Defines></Defines>
<ForceIncludes></ForceIncludes>
</ConfigAndPlatform>
<Config>
<Name>Debug</Name>
<Defines></Defines>
</Config>
<Platform>
<Name>x64</Name>
<Defines></Defines>
</Platform>
</ConfigProperties>
<Children></Children> <Children></Children>
</Workspace> </Workspace>
</N10X> </N10X>

View File

@ -6,6 +6,7 @@
#include "AbilitySystemComponent.h" #include "AbilitySystemComponent.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#include "Networking/GasaNetLibrary.h" #include "Networking/GasaNetLibrary.h"
#include "GameplayEffectExtension.h"
UGasaAttributeSet::UGasaAttributeSet() UGasaAttributeSet::UGasaAttributeSet()
{ {
@ -16,6 +17,34 @@ UGasaAttributeSet::UGasaAttributeSet()
} }
#pragma region Rep Notifies #pragma region Rep Notifies
void UGasaAttributeSet::Client_OnRep_Strength( FGameplayAttributeData& PrevStrength )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Strength ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Strength, PrevStrength );
}
void UGasaAttributeSet::Client_OnRep_Intelligence( FGameplayAttributeData& PrevIntelligence )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Intelligence ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(
FGameplayAttribute( UGasaAttributeSetProperty ), Intelligence, PrevIntelligence
);
}
void UGasaAttributeSet::Client_OnRep_Resilience( FGameplayAttributeData& PrevResilience )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Resilience ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(
FGameplayAttribute( UGasaAttributeSetProperty ), Resilience, PrevResilience
);
}
void UGasaAttributeSet::Client_OnRep_Vigor( FGameplayAttributeData& PrevVigor )
{
// From GAMEPLAYATTRIBUTE_REPNOTIFY
static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Vigor ) );
GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Vigor, PrevVigor );
}
void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth ) void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth )
{ {
// From GAMEPLAYATTRIBUTE_REPNOTIFY // From GAMEPLAYATTRIBUTE_REPNOTIFY
@ -47,12 +76,63 @@ void UGasaAttributeSet::PostGameplayEffectExecute( FGameplayEffectModCallbackDat
Super::PostGameplayEffectExecute( Data ); Super::PostGameplayEffectExecute( Data );
FEffectProperties Props; FEffectProperties Props;
Props.Populate( Data ); Props.Populate( Data );
if ( Data.EvaluatedData.Attribute == GetStrengthAttribute() )
{
SetStrength( FMath::Clamp( GetStrength(), 0, 999.000000 ) );
}
if ( Data.EvaluatedData.Attribute == GetIntelligenceAttribute() )
{
SetIntelligence( FMath::Clamp( GetIntelligence(), 0, 999.000000 ) );
}
if ( Data.EvaluatedData.Attribute == GetResilienceAttribute() )
{
SetResilience( FMath::Clamp( GetResilience(), 0, 999.000000 ) );
}
if ( Data.EvaluatedData.Attribute == GetVigorAttribute() )
{
SetVigor( FMath::Clamp( GetVigor(), 0, 999.000000 ) );
}
if ( Data.EvaluatedData.Attribute == GetHealthAttribute() )
{
SetHealth( FMath::Clamp( GetHealth(), 0, GetMaxHealth() ) );
}
if ( Data.EvaluatedData.Attribute == GetMaxHealthAttribute() )
{
SetMaxHealth( FMath::Clamp( GetMaxHealth(), 0, 99999.000000 ) );
}
if ( Data.EvaluatedData.Attribute == GetManaAttribute() )
{
SetMana( FMath::Clamp( GetMana(), 0, GetMaxMana() ) );
}
if ( Data.EvaluatedData.Attribute == GetMaxManaAttribute() )
{
SetMaxMana( FMath::Clamp( GetMaxMana(), 0, 99999.000000 ) );
}
PostAttributeChange_Custom();
} }
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 == GetStrengthAttribute() )
{
NewValue = FMath::Clamp( NewValue, 0, 999.000000 );
}
if ( Attribute == GetIntelligenceAttribute() )
{
NewValue = FMath::Clamp( NewValue, 0, 999.000000 );
}
if ( Attribute == GetResilienceAttribute() )
{
NewValue = FMath::Clamp( NewValue, 0, 999.000000 );
}
if ( Attribute == GetVigorAttribute() )
{
NewValue = FMath::Clamp( NewValue, 0, 999.000000 );
}
if ( Attribute == GetHealthAttribute() ) if ( Attribute == GetHealthAttribute() )
{ {
NewValue = FMath::Clamp( NewValue, 0, GetMaxHealth() ); NewValue = FMath::Clamp( NewValue, 0, GetMaxHealth() );
@ -69,12 +149,18 @@ void UGasaAttributeSet::PreAttributeChange( FGameplayAttribute const& Attribute,
{ {
NewValue = FMath::Clamp( NewValue, 0, 99999.000000 ); NewValue = FMath::Clamp( NewValue, 0, 99999.000000 );
} }
PreAttributeChange_Custom();
} }
void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const
{ {
Super::GetLifetimeReplicatedProps( OutLifetimeProps ); Super::GetLifetimeReplicatedProps( OutLifetimeProps );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Strength );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Intelligence );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Resilience );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Vigor );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Health ); DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Health );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, MaxHealth ); DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, MaxHealth );
DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Mana ); DOREPLIFETIME_DEFAULT_GAS( UGasaAttributeSet, Mana );

View File

@ -11,6 +11,19 @@ class GASA_API UGasaAttributeSet : public UAttributeSet
public: public:
UGasaAttributeSet(); UGasaAttributeSet();
// Primary Attribute Fields
UPROPERTY( ReplicatedUsing = Client_OnRep_Strength, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Strength;
UPROPERTY( ReplicatedUsing = Client_OnRep_Intelligence, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Intelligence;
UPROPERTY( ReplicatedUsing = Client_OnRep_Resilience, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Resilience;
UPROPERTY( ReplicatedUsing = Client_OnRep_Vigor, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData Vigor;
// Vital Attribute Fields
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_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
@ -20,6 +33,14 @@ public:
UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" )
FGameplayAttributeData MaxMana; FGameplayAttributeData MaxMana;
UFUNCTION()
void Client_OnRep_Strength( FGameplayAttributeData& PrevStrength );
UFUNCTION()
void Client_OnRep_Intelligence( FGameplayAttributeData& PrevIntelligence );
UFUNCTION()
void Client_OnRep_Resilience( FGameplayAttributeData& PrevResilience );
UFUNCTION()
void Client_OnRep_Vigor( FGameplayAttributeData& PrevVigor );
UFUNCTION() UFUNCTION()
void Client_OnRep_Health( FGameplayAttributeData& PrevHealth ); void Client_OnRep_Health( FGameplayAttributeData& PrevHealth );
UFUNCTION() UFUNCTION()
@ -30,6 +51,26 @@ public:
void Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana ); void Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana );
#pragma region Getters #pragma region Getters
static FGameplayAttribute GetStrengthAttribute()
{
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Strength ) );
return Prop;
}
static FGameplayAttribute GetIntelligenceAttribute()
{
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Intelligence ) );
return Prop;
}
static FGameplayAttribute GetResilienceAttribute()
{
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Resilience ) );
return Prop;
}
static FGameplayAttribute GetVigorAttribute()
{
static FProperty* Prop = FindFieldChecked<FProperty>( UGasaAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Vigor ) );
return Prop;
}
static FGameplayAttribute GetHealthAttribute() 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 ) );
@ -51,6 +92,10 @@ public:
return Prop; return Prop;
} }
FORCEINLINE float GetStrength() const { return Strength.GetCurrentValue(); }
FORCEINLINE float GetIntelligence() const { return Intelligence.GetCurrentValue(); }
FORCEINLINE float GetResilience() const { return Resilience.GetCurrentValue(); }
FORCEINLINE float GetVigor() const { return Vigor.GetCurrentValue(); }
FORCEINLINE float GetHealth() const { return Health.GetCurrentValue(); } FORCEINLINE float GetHealth() const { return Health.GetCurrentValue(); }
FORCEINLINE float GetMaxHealth() const { return MaxHealth.GetCurrentValue(); } FORCEINLINE float GetMaxHealth() const { return MaxHealth.GetCurrentValue(); }
FORCEINLINE float GetMana() const { return Mana.GetCurrentValue(); } FORCEINLINE float GetMana() const { return Mana.GetCurrentValue(); }
@ -59,11 +104,35 @@ public:
#pragma region Setters #pragma region Setters
FORCEINLINE void FORCEINLINE void
SetHealth( float NewVal ); SetStrength( float NewVal );
FORCEINLINE void SetIntelligence( float NewVal );
FORCEINLINE void SetResilience( float NewVal );
FORCEINLINE void SetVigor( 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 );
FORCEINLINE void InitStrength( float NewVal )
{
Strength.SetBaseValue( NewVal );
Strength.SetCurrentValue( NewVal );
}
FORCEINLINE void InitIntelligence( float NewVal )
{
Intelligence.SetBaseValue( NewVal );
Intelligence.SetCurrentValue( NewVal );
}
FORCEINLINE void InitResilience( float NewVal )
{
Resilience.SetBaseValue( NewVal );
Resilience.SetCurrentValue( NewVal );
}
FORCEINLINE void InitVigor( float NewVal )
{
Vigor.SetBaseValue( NewVal );
Vigor.SetCurrentValue( NewVal );
}
FORCEINLINE void InitHealth( float NewVal ) FORCEINLINE void InitHealth( float NewVal )
{ {
Health.SetBaseValue( NewVal ); Health.SetBaseValue( NewVal );

View File

@ -6,6 +6,42 @@
#pragma region Attribute Setters #pragma region Attribute Setters
FORCEINLINE FORCEINLINE
void UGasaAttributeSet::SetStrength( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetStrengthAttribute(), NewVal );
};
}
FORCEINLINE
void UGasaAttributeSet::SetIntelligence( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetIntelligenceAttribute(), NewVal );
};
}
FORCEINLINE
void UGasaAttributeSet::SetResilience( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetResilienceAttribute(), NewVal );
};
}
FORCEINLINE
void UGasaAttributeSet::SetVigor( float NewVal )
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if ( ensure( AbilityComp ) )
{
AbilityComp->SetNumericAttributeBase( GetVigorAttribute(), NewVal );
};
}
FORCEINLINE
void UGasaAttributeSet::SetHealth( float NewVal ) void UGasaAttributeSet::SetHealth( float NewVal )
{ {
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent(); UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();

View File

@ -64,6 +64,18 @@ AGasaCharacter::AGasaCharacter()
ACharacter::SetReplicateMovement(true); ACharacter::SetReplicateMovement(true);
} }
#pragma region Ability System
void AGasaCharacter::InitDefaultAttributes()
{
UAbilitySystemComponent* ASC = GetAbilitySystemComponent();
ensure(ASC);
ensure(DefaultAttributes);
FGameplayEffectContextHandle Context = ASC->MakeEffectContext();
FGameplayEffectSpecHandle Spec = ASC->MakeOutgoingSpec(DefaultAttributes, 1.0f, Context );
ASC->ApplyGameplayEffectSpecToTarget( * Spec.Data, ASC );
}
#pragma endregion Ability System
#pragma region GameFramework #pragma region GameFramework
void AGasaCharacter::Controller_OnPawnPossessed() void AGasaCharacter::Controller_OnPawnPossessed()
{ {
@ -186,6 +198,8 @@ void AGasaCharacter::BeginPlay()
{ {
AbilitySystem->InitAbilityActorInfo(this, this); AbilitySystem->InitAbilityActorInfo(this, this);
Cast<UGasaAbilitySystemComp>(AbilitySystem)->OnAbilityActorInfoSet(); Cast<UGasaAbilitySystemComp>(AbilitySystem)->OnAbilityActorInfoSet();
InitDefaultAttributes();
} }
} }
@ -233,3 +247,4 @@ void AGasaCharacter::Tick(float DeltaSeconds)
} }
} }
#pragma endregion Actor #pragma endregion Actor

View File

@ -34,6 +34,11 @@ public:
UPROPERTY(EditAnywhere, Category="Ability System") UPROPERTY(EditAnywhere, Category="Ability System")
TObjectPtr<UAttributeSet> Attributes; TObjectPtr<UAttributeSet> Attributes;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Ability System")
TSubclassOf<UGameplayEffect> DefaultAttributes;
void InitDefaultAttributes();
#pragma endregion Ability System #pragma endregion Ability System
#pragma region Combat #pragma region Combat

View File

@ -109,12 +109,12 @@ void UGlobeProgressBar::SetPercentage(float CurrentValue, float MaxValue)
UWorld* World = GetWorld(); UWorld* World = GetWorld();
FTimerManager& TM = World->GetTimerManager(); FTimerManager& TM = World->GetTimerManager();
if ( CurrentValueClamped < PreviousValue ) if ( CurrentValueClamped <= PreviousValue )
{ {
// Timer will auto-clear previous set delay // Timer will auto-clear previous set delay
TM.SetTimer( GhostPercentChangeTimer, this, & UGlobeProgressBar::GhostPercentUpdateViaTimer, GhostPercentChangeDelay ); TM.SetTimer( GhostPercentChangeTimer, this, & UGlobeProgressBar::GhostPercentUpdateViaTimer, GhostPercentChangeDelay );
} }
else else if ( Bar->GetPercent() >= GhostBar->GetPercent() )
{ {
if ( TM.TimerExists( GhostPercentChangeTimer )) if ( TM.TimerExists( GhostPercentChangeTimer ))
TM.ClearTimer( GhostPercentChangeTimer ); TM.ClearTimer( GhostPercentChangeTimer );
@ -179,7 +179,7 @@ void UGlobeProgressBar::NativeTick(const FGeometry& MyGeometry, float InDeltaTim
FTimerManager& TM = World->GetTimerManager(); FTimerManager& TM = World->GetTimerManager();
// Ghost Percent Interpolation // Ghost Percent Interpolation
if ( ! TM.TimerExists( GhostPercentChangeTimer )) if ( ! TM.TimerExists( GhostPercentChangeTimer ) )
{ {
float NextPercent = FMath::FInterpTo( GhostBar->GetPercent(), GhostTargetPercent, InDeltaTime, GhostPercentInterpolationSpeed ); float NextPercent = FMath::FInterpTo( GhostBar->GetPercent(), GhostTargetPercent, InDeltaTime, GhostPercentInterpolationSpeed );
GhostBar->SetPercent( NextPercent ); GhostBar->SetPercent( NextPercent );

View File

@ -88,7 +88,7 @@ int gen_main()
// gen_netslime_interfaces(); // gen_netslime_interfaces();
// One offs // One offs
if (1) if (0)
{ {
// ue_parse_testing(); // ue_parse_testing();
swap_SBlueprintActionMenu_Construct(); swap_SBlueprintActionMenu_Construct();

View File

@ -9,7 +9,7 @@
void gen_UHostWidgetController() void gen_UHostWidgetController()
{ {
Array<GAS_AttributeEntry> attribute_fields = get_gasa_attribute_fields(); Array<GAS_AttributeEntry> attribute_fields = get_gasa_vital_attribute_fields();
CodeBody ori_HostWidgetController_header = parse_file(path_gasa_ui "HostWidgetController.h"); CodeBody ori_HostWidgetController_header = parse_file(path_gasa_ui "HostWidgetController.h");
{ {

View File

@ -1,4 +1,4 @@
// Used in the GasaGen.cpp translation unit // Used in the GasaGen.cpp translation unit
#if GASA_INTELLISENSE_DIRECTIVES #if GASA_INTELLISENSE_DIRECTIVES
#pragma once #pragma once
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
@ -10,6 +10,8 @@
struct GAS_AttributeEntry struct GAS_AttributeEntry
{ {
StringCached Name; StringCached Name;
// StringCached Description;
// StringCached Category;
StringCached MinName; StringCached MinName;
StringCached MaxName; StringCached MaxName;
float Min; float Min;
@ -25,12 +27,58 @@ void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name
void def_attribute_field_initers ( CodeBody body, Array<GAS_AttributeEntry> properties ); void def_attribute_field_initers ( CodeBody body, Array<GAS_AttributeEntry> properties );
void impl_attribute_fields ( CodeBody body, StrC class_name, Array<GAS_AttributeEntry> properties ); void impl_attribute_fields ( CodeBody body, StrC class_name, Array<GAS_AttributeEntry> properties );
Array<GAS_AttributeEntry> get_gasa_attribute_fields() Array<GAS_AttributeEntry> get_gasa_primary_attribute_fields()
{ {
local_persist local_persist
Array<GAS_AttributeEntry> attribute_fields = Array<GAS_AttributeEntry>::init_reserve(GlobalAllocator, 64); Array<GAS_AttributeEntry> attribute_fields = Array<GAS_AttributeEntry>::init_reserve(GlobalAllocator, 64);
for (local_persist s32 do_once = 0; do_once == 0; ++ do_once) { for (local_persist s32 do_once = 0; do_once == 0; ++ do_once)
{
StringCached str_Strength = get_cached_string(txt("Strength"));
StringCached str_Intelligence = get_cached_string(txt("Intelligence"));
StringCached str_Resilience = get_cached_string(txt("Resilience"));
StringCached str_Vigor = get_cached_string(txt("Vigor"));
GAS_AttributeEntry Strength = { str_Strength, {nullptr}, {nullptr}, 0, 999.f };
GAS_AttributeEntry Intelligence = { str_Intelligence, {nullptr}, {nullptr}, 0, 999.f };
GAS_AttributeEntry Resilience = { str_Resilience, {nullptr}, {nullptr}, 0, 999.f };
GAS_AttributeEntry Vigor = { str_Vigor, {nullptr}, {nullptr}, 0, 999.f };
attribute_fields.append(Strength);
attribute_fields.append(Intelligence);
attribute_fields.append(Resilience);
attribute_fields.append(Vigor);
}
return attribute_fields;
}
Array<GAS_AttributeEntry> get_gasa_secondary_attribute_fields()
{
local_persist
Array<GAS_AttributeEntry> attribute_fields = Array<GAS_AttributeEntry>::init_reserve(GlobalAllocator, 64);
for (local_persist s32 do_once = 0; do_once == 0; ++ do_once)
{
// StringCached str_Strength = get_cached_string(txt("Strength"));
// StringCached str_Intelligence = get_cached_string(txt("Intelligence"));
// StringCached str_Resilience = get_cached_string(txt("Resilience"));
// StringCached str_Vigor = get_cached_string(txt("Vigor"));
//
// GAS_AttributeEntry Health = { str_Health, {nullptr}, str_MaxHealth, 0, 100.f };
// GAS_AttributeEntry MaxHealth = { str_MaxHealth, {nullptr}, {nullptr}, 0, 99999.f };
// GAS_AttributeEntry Mana = { str_Mana, {nullptr}, str_MaxMana, 0, 50.f };
// GAS_AttributeEntry MaxMana = { str_MaxMana, {nullptr}, {nullptr}, 0, 99999.f };
}
return attribute_fields;
}
Array<GAS_AttributeEntry> get_gasa_vital_attribute_fields()
{
local_persist
Array<GAS_AttributeEntry> attribute_fields = Array<GAS_AttributeEntry>::init_reserve(GlobalAllocator, 64);
for (local_persist s32 do_once = 0; do_once == 0; ++ do_once)
{
StringCached str_Health = get_cached_string(txt("Health")); StringCached str_Health = get_cached_string(txt("Health"));
StringCached str_MaxHealth = get_cached_string(txt("MaxHealth")); StringCached str_MaxHealth = get_cached_string(txt("MaxHealth"));
StringCached str_Mana = get_cached_string(txt("Mana")); StringCached str_Mana = get_cached_string(txt("Mana"));
@ -54,7 +102,17 @@ void gen_UGasaAttributeSet()
CodeType type_UAttributeSet = def_type( txt("UAttributeSet") ); CodeType type_UAttributeSet = def_type( txt("UAttributeSet") );
CodeComment generation_notice = def_comment(txt("Generated by GasaGen/GasaGen_UGasaAttributeSet.cpp")); CodeComment generation_notice = def_comment(txt("Generated by GasaGen/GasaGen_UGasaAttributeSet.cpp"));
Array<GAS_AttributeEntry> attribute_fields = get_gasa_attribute_fields(); Array<GAS_AttributeEntry> primary_attribute_fields = get_gasa_primary_attribute_fields();
Array<GAS_AttributeEntry> secondary_attribute_fields = get_gasa_secondary_attribute_fields();
Array<GAS_AttributeEntry> vital_attribute_fields = get_gasa_vital_attribute_fields();
s32 all_attrib_count = primary_attribute_fields.num() + secondary_attribute_fields.num() + vital_attribute_fields.num();
Array< GAS_AttributeEntry>
all_attribute_fields = Array<GAS_AttributeEntry>::init_reserve(GlobalAllocator, all_attrib_count);
all_attribute_fields.append( primary_attribute_fields);
all_attribute_fields.append( secondary_attribute_fields);
all_attribute_fields.append( vital_attribute_fields);
StrC class_name = txt("UGasaAttributeSet"); StrC class_name = txt("UGasaAttributeSet");
@ -67,7 +125,7 @@ void gen_UGasaAttributeSet()
CodeInclude Include_AttributeSet = def_include(txt("AttributeSet.h")); CodeInclude Include_AttributeSet = def_include(txt("AttributeSet.h"));
CodeInclude Include_GasaAttributeSet_Generated = def_include(txt("GasaAttributeSet.generated.h")); CodeInclude Include_GasaAttributeSet_Generated = def_include(txt("GasaAttributeSet.generated.h"));
CodeAttributes api_attribute= def_attributes( UModule_GASA_API->Name); CodeAttributes api_attribute = def_attributes( UModule_GASA_API->Name);
CodeClass GasaAttributeSet = {}; CodeClass GasaAttributeSet = {};
{ {
@ -79,25 +137,50 @@ void gen_UGasaAttributeSet()
body.append( def_constructor() ); body.append( def_constructor() );
body.append(fmt_newline); body.append(fmt_newline);
def_attribute_properties( body, attribute_fields); body.append( def_comment(txt("Primary Attribute Fields")));
body.append(fmt_newline); body.append(fmt_newline);
def_attribute_field_on_reps( body, attribute_fields); def_attribute_properties( body, primary_attribute_fields);
body.append(fmt_newline);
body.append(fmt_newline);
// body.append( def_comment(txt("Secondary Attribute Fields")));
// body.append(fmt_newline);
// def_attribute_properties( body, secondary_attribute_fields);
// body.append(fmt_newline);
// body.append(fmt_newline);
body.append( def_comment(txt("Vital Attribute Fields")));
body.append(fmt_newline);
def_attribute_properties( body, vital_attribute_fields);
body.append(fmt_newline);
def_attribute_field_on_reps( body, primary_attribute_fields);
def_attribute_field_on_reps( body, secondary_attribute_fields);
def_attribute_field_on_reps( body, vital_attribute_fields);
body.append(fmt_newline); body.append(fmt_newline);
body.append( fmt_newline ); body.append( fmt_newline );
body.append( def_pragma(txt( "region Getters" ))); body.append( def_pragma(txt( "region Getters" )));
def_attribute_field_property_getters( body, class_name, attribute_fields ); def_attribute_field_property_getters( body, class_name, primary_attribute_fields );
def_attribute_field_property_getters( body, class_name, secondary_attribute_fields );
def_attribute_field_property_getters( body, class_name, vital_attribute_fields );
body.append( fmt_newline ); body.append( fmt_newline );
def_attribute_field_value_getters( body, attribute_fields ); def_attribute_field_value_getters( body, primary_attribute_fields );
def_attribute_field_value_getters( body, secondary_attribute_fields );
def_attribute_field_value_getters( body, vital_attribute_fields );
body.append( def_pragma(txt( "endregion Getters" ))); body.append( def_pragma(txt( "endregion Getters" )));
body.append( fmt_newline ); body.append( fmt_newline );
body.append( def_pragma(txt( "region Setters" ))); body.append( def_pragma(txt( "region Setters" )));
def_attribute_field_value_setters( body, attribute_fields ); def_attribute_field_value_setters( body, primary_attribute_fields );
def_attribute_field_value_setters( body, secondary_attribute_fields );
def_attribute_field_value_setters( body, vital_attribute_fields );
body.append( fmt_newline ); body.append( fmt_newline );
body.append( fmt_newline ); body.append( fmt_newline );
def_attribute_field_initers( body, attribute_fields ); def_attribute_field_initers( body, primary_attribute_fields );
def_attribute_field_initers( body, secondary_attribute_fields );
def_attribute_field_initers( body, vital_attribute_fields );
body.append( def_pragma(txt( "endregion Setters" ))); body.append( def_pragma(txt( "endregion Setters" )));
body.append( fmt_newline ); body.append( fmt_newline );
@ -143,7 +226,7 @@ void gen_UGasaAttributeSet()
CodeBody body = def_body(CodeT::Global_Body); CodeBody body = def_body(CodeT::Global_Body);
{ {
def_attribute_field_property_setter_inlines( body, class_name, attribute_fields ); def_attribute_field_property_setter_inlines( body, class_name, all_attribute_fields );
} }
inlines.print(body); inlines.print(body);
inlines.print(fmt_newline); inlines.print(fmt_newline);
@ -175,6 +258,7 @@ void gen_UGasaAttributeSet()
source.print( def_include( txt("AbilitySystemComponent.h"))); source.print( def_include( txt("AbilitySystemComponent.h")));
source.print( def_include( txt("Net/UnrealNetwork.h"))); source.print( def_include( txt("Net/UnrealNetwork.h")));
source.print( def_include( txt("Networking/GasaNetLibrary.h"))); source.print( def_include( txt("Networking/GasaNetLibrary.h")));
source.print( def_include( txt("GameplayEffectExtension.h")));
{ {
CodeBody body = def_body( CodeT::Global_Body ); CodeBody body = def_body( CodeT::Global_Body );
body.append(fmt_newline); body.append(fmt_newline);
@ -190,25 +274,20 @@ void gen_UGasaAttributeSet()
)); ));
body.append(constructor_for_UGasaAttributeSet ); body.append(constructor_for_UGasaAttributeSet );
impl_attribute_fields( body, class_name, attribute_fields); impl_attribute_fields( body, class_name, all_attribute_fields);
Code PostGameplayEffectExecute = parse_function( code(
void UGasaAttributeSet::PostGameplayEffectExecute(FGameplayEffectModCallbackData const& Data)
{
Super::PostGameplayEffectExecute(Data);
FEffectProperties Props;
Props.Populate(Data);
}
));
body.append(PostGameplayEffectExecute);
body.append(fmt_newline);
CodeFn PostGameplayEffectExecute;
CodeFn PreAttributeChange; CodeFn PreAttributeChange;
{ {
CodeBody attribute_clamps = def_body( CodeT::Function_Body ); CodeBody pre_attribute_clamps = def_body( CodeT::Function_Body );
attribute_clamps.append(fmt_newline); pre_attribute_clamps.append(fmt_newline);
attribute_clamps.append(fmt_newline); pre_attribute_clamps.append(fmt_newline);
for (GAS_AttributeEntry field : attribute_fields)
CodeBody post_attribute_clamps = def_body( CodeT::Function_Body );
post_attribute_clamps.append(fmt_newline);
post_attribute_clamps.append(fmt_newline);
for (GAS_AttributeEntry field : all_attribute_fields)
{ {
String clamp_min; String clamp_min;
if (field.MinName.Data) if (field.MinName.Data)
@ -222,27 +301,61 @@ void gen_UGasaAttributeSet()
else else
clamp_max = String::fmt_buf(GlobalAllocator, "%f", field.Max); clamp_max = String::fmt_buf(GlobalAllocator, "%f", field.Max);
attribute_clamps.append( code_fmt( pre_attribute_clamps.append( code_fmt(
"field", (StrC)field.Name, "field", (StrC)field.Name,
"clamp_min", (StrC)clamp_min, "clamp_min", (StrC)clamp_min,
"clamp_max", (StrC)clamp_max, "clamp_max", (StrC)clamp_max,
stringize( stringize(
if (Attribute == Get<field>Attribute()) if (Attribute == Get<field>Attribute())
{ {
NewValue = FMath::Clamp(NewValue, <clamp_min>, <clamp_max>); NewValue = FMath::Clamp(NewValue, <clamp_min>, <clamp_max>);
} }
)));
post_attribute_clamps.append( code_fmt(
"field", (StrC)field.Name,
"clamp_min", (StrC)clamp_min,
"clamp_max", (StrC)clamp_max,
stringize(
if ( Data.EvaluatedData.Attribute == Get<field>Attribute() )
{
Set<field>(FMath::Clamp(Get<field>(), <clamp_min>, <clamp_max> ));
}
))); )));
} }
attribute_clamps.append(fmt_newline);
attribute_clamps.append(fmt_newline); pre_attribute_clamps.append(fmt_newline);
PreAttributeChange = parse_function( token_fmt( "attribute_clamps", (StrC)attribute_clamps.to_string(), stringize( pre_attribute_clamps.append(fmt_newline);
post_attribute_clamps.append(fmt_newline);
post_attribute_clamps.append(fmt_newline);
PreAttributeChange = parse_function( token_fmt( "attribute_clamps", (StrC)pre_attribute_clamps.to_string(), stringize(
void UGasaAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) void UGasaAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{ {
Super::PreAttributeChange(Attribute, NewValue); Super::PreAttributeChange(Attribute, NewValue);
<attribute_clamps> <attribute_clamps>
PreAttributeChange_Custom();
}
)));
PostGameplayEffectExecute = parse_function( token_fmt( "attribute_clamps", (StrC)post_attribute_clamps.to_string(), stringize(
void UGasaAttributeSet::PostGameplayEffectExecute(FGameplayEffectModCallbackData const& Data)
{
Super::PostGameplayEffectExecute(Data);
FEffectProperties Props;
Props.Populate(Data);
<attribute_clamps>
PostAttributeChange_Custom();
} }
))); )));
} }
body.append(PostGameplayEffectExecute);
body.append(fmt_newline);
body.append(PreAttributeChange); body.append(PreAttributeChange);
body.append(fmt_newline); body.append(fmt_newline);
@ -251,7 +364,7 @@ void gen_UGasaAttributeSet()
CodeBody field_lifetimes = def_body( CodeT::Function_Body); CodeBody field_lifetimes = def_body( CodeT::Function_Body);
field_lifetimes.append(fmt_newline); field_lifetimes.append(fmt_newline);
field_lifetimes.append(fmt_newline); field_lifetimes.append(fmt_newline);
for (GAS_AttributeEntry field : attribute_fields) for (GAS_AttributeEntry field : all_attribute_fields)
{ {
field_lifetimes.append( code_fmt( "field", (StrC)field.Name, stringize( field_lifetimes.append( code_fmt( "field", (StrC)field.Name, stringize(
DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, <field>); DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, <field>);

View File

@ -1558,6 +1558,11 @@ struct Array
return 2 * value + 8; return 2 * value + 8;
} }
bool append( Array other )
{
return append( other, other.num() );
}
bool append( Type value ) bool append( Type value )
{ {
Header* header = get_header(); Header* header = get_header();