45. PreAttributeChange
This commit is contained in:
		| @@ -8,9 +8,9 @@ | |||||||
|  |  | ||||||
| UGasaAttributeSet::UGasaAttributeSet() | UGasaAttributeSet::UGasaAttributeSet() | ||||||
| { | { | ||||||
| 	InitHealth( 50.f ); | 	InitHealth( 100.f ); | ||||||
| 	InitMaxHealth( 100.f ); | 	InitMaxHealth( 100.f ); | ||||||
| 	InitMana( 25.f ); | 	InitMana( 50.f ); | ||||||
| 	InitMaxMana( 50.f ); | 	InitMaxMana( 50.f ); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -41,6 +41,27 @@ void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMan | |||||||
| } | } | ||||||
| #pragma endregion Rep Notifies | #pragma endregion Rep Notifies | ||||||
|  |  | ||||||
|  | void UGasaAttributeSet::PreAttributeChange( FGameplayAttribute const& Attribute, float& NewValue ) | ||||||
|  | { | ||||||
|  | 	Super::PreAttributeChange( Attribute, NewValue ); | ||||||
|  |  | ||||||
|  | 	if ( Attribute == GetHealthAttribute() ) | ||||||
|  | 	{ | ||||||
|  | 		NewValue = FMath::Clamp( NewValue, 0, GetMaxHealth() ); | ||||||
|  | 	} | ||||||
|  | 	if ( Attribute == GetMaxHealthAttribute() ) | ||||||
|  | 	{ | ||||||
|  | 		NewValue = FMath::Clamp( NewValue, 0, 99999.000000 ); | ||||||
|  | 	} | ||||||
|  | 	if ( Attribute == GetManaAttribute() ) | ||||||
|  | 	{ | ||||||
|  | 		NewValue = FMath::Clamp( NewValue, 0, GetMaxMana() ); | ||||||
|  | 	} | ||||||
|  | 	if ( Attribute == GetMaxManaAttribute() ) | ||||||
|  | 	{ | ||||||
|  | 		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 ); | ||||||
|   | |||||||
| @@ -9,20 +9,16 @@ class GASA_API UGasaAttributeSet : public UAttributeSet | |||||||
| { | { | ||||||
| 	GENERATED_BODY() | 	GENERATED_BODY() | ||||||
| public: | public: | ||||||
| 	UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) |  | ||||||
| 	FGameplayAttributeData Health; |  | ||||||
|  |  | ||||||
| 	UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) |  | ||||||
| 	FGameplayAttributeData MaxHealth; |  | ||||||
|  |  | ||||||
| 	UPROPERTY( ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) |  | ||||||
| 	FGameplayAttributeData Mana; |  | ||||||
|  |  | ||||||
| 	UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) |  | ||||||
| 	FGameplayAttributeData MaxMana; |  | ||||||
|  |  | ||||||
| 	UGasaAttributeSet(); | 	UGasaAttributeSet(); | ||||||
|  |  | ||||||
|  | 	UPROPERTY( ReplicatedUsing = Client_OnRep_Health, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) | ||||||
|  | 	FGameplayAttributeData Health; | ||||||
|  | 	UPROPERTY( ReplicatedUsing = Client_OnRep_MaxHealth, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) | ||||||
|  | 	FGameplayAttributeData MaxHealth; | ||||||
|  | 	UPROPERTY( ReplicatedUsing = Client_OnRep_Mana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) | ||||||
|  | 	FGameplayAttributeData Mana; | ||||||
|  | 	UPROPERTY( ReplicatedUsing = Client_OnRep_MaxMana, EditAnywhere, BlueprintReadWrite, Category = "Attributes" ) | ||||||
|  | 	FGameplayAttributeData MaxMana; | ||||||
|  |  | ||||||
| 	UFUNCTION() | 	UFUNCTION() | ||||||
| 	void Client_OnRep_Health( FGameplayAttributeData& PrevHealth ); | 	void Client_OnRep_Health( FGameplayAttributeData& PrevHealth ); | ||||||
| @@ -62,8 +58,7 @@ public: | |||||||
| 	#pragma endregion Getters | 	#pragma endregion Getters | ||||||
|  |  | ||||||
| #pragma region Setters | #pragma region Setters | ||||||
| 	    FORCEINLINE void | 	FORCEINLINE void SetHealth( float NewVal ); | ||||||
| 	                 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 ); | ||||||
| @@ -90,8 +85,11 @@ public: | |||||||
| 	} | 	} | ||||||
| 	#pragma endregion Setters | 	#pragma endregion Setters | ||||||
|  |  | ||||||
|  | #pragma region AttributeSet | ||||||
|  | 	    void PreAttributeChange( const FGameplayAttribute& Attribute, float& NewValue ) override; | ||||||
|  | #pragma endregion AttributeSet | ||||||
|  |  | ||||||
| #pragma region UObject | #pragma region UObject | ||||||
| 	    void | 	    void GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override; | ||||||
| 	    GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override; |  | ||||||
| #pragma endregion UObject | #pragma endregion UObject | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -77,6 +77,9 @@ CodeBody parse_file( char const* path ) { | |||||||
| 	return code; | 	return code; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // inline | ||||||
|  | // CodeConstructor find_constructor( StrC parent_name, ) | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void format_file( char const* path ) | void format_file( char const* path ) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -4,11 +4,12 @@ | |||||||
| #include "gen.hpp" | #include "gen.hpp" | ||||||
| #include "gen.builder.hpp" | #include "gen.builder.hpp" | ||||||
| #include "GasaGenCommon.cpp" | #include "GasaGenCommon.cpp" | ||||||
|  | #include "GasaGen_UGasaAttributeSet.cpp" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| void gen_UHostWidgetController() | void gen_UHostWidgetController() | ||||||
| { | { | ||||||
| 	Array<StringCached> attribute_fields = get_gasa_attribute_fields(); | 	Array<GAS_AttributeEntry> attribute_fields = get_gasa_attribute_fields(); | ||||||
|  |  | ||||||
| 	CodeBody ori_HostWidgetController_header = parse_file(path_gasa_ui "HostWidgetController.h"); | 	CodeBody ori_HostWidgetController_header = parse_file(path_gasa_ui "HostWidgetController.h"); | ||||||
| 	{ | 	{ | ||||||
| @@ -64,21 +65,21 @@ void gen_UHostWidgetController() | |||||||
|  |  | ||||||
| 			for ( s32 id = 0; id < attribute_fields.num(); ++id ) | 			for ( s32 id = 0; id < attribute_fields.num(); ++id ) | ||||||
| 			{ | 			{ | ||||||
| 				StringCached attribute_field = attribute_fields[id]; | 				GAS_AttributeEntry attribute_field = attribute_fields[id]; | ||||||
|  |  | ||||||
| 				attribute_events.append( code_str( | 				attribute_events.append( code_str( | ||||||
| 					UPROPERTY(BlueprintAssignable, Category = "Attributes") | 					UPROPERTY(BlueprintAssignable, Category = "Attributes") | ||||||
| 				)); | 				)); | ||||||
| 				attribute_events.append(fmt_newline); | 				attribute_events.append(fmt_newline); | ||||||
| 				attribute_events.append( parse_variable( | 				attribute_events.append( parse_variable( | ||||||
| 					token_fmt( "field", (StrC) attribute_field, stringize( FAttributeFloatChangedSig Event_On<field>Changed; )) | 					token_fmt( "field", (StrC) attribute_field.Name, stringize( FAttributeFloatChangedSig Event_On<field>Changed; )) | ||||||
| 				)); | 				)); | ||||||
| 				attribute_events.append(fmt_newline); | 				attribute_events.append(fmt_newline); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			for ( s32 id = 0; id < attribute_fields.num(); ++id ) | 			for ( s32 id = 0; id < attribute_fields.num(); ++id ) | ||||||
| 			{ | 			{ | ||||||
| 				StringCached attribute_field = attribute_fields[id]; | 				StringCached attribute_field = attribute_fields[id].Name; | ||||||
|  |  | ||||||
| 				attribute_events.append( parse_function( | 				attribute_events.append( parse_function( | ||||||
| 					token_fmt( "field", (StrC) attribute_field, stringize( void <field>Changed(FOnAttributeChangeData const& Data); )) | 					token_fmt( "field", (StrC) attribute_field, stringize( void <field>Changed(FOnAttributeChangeData const& Data); )) | ||||||
| @@ -154,9 +155,9 @@ void gen_UHostWidgetController() | |||||||
| 		CodeFn BroadcastInitialValues = NoCode; | 		CodeFn BroadcastInitialValues = NoCode; | ||||||
| 		{ | 		{ | ||||||
| 			CodeBody broadcast_calls = def_body(ECode::Function_Body); | 			CodeBody broadcast_calls = def_body(ECode::Function_Body); | ||||||
| 			for (StringCached field : attribute_fields) | 			for (GAS_AttributeEntry field : attribute_fields) | ||||||
| 			{ | 			{ | ||||||
| 				broadcast_calls.append( code_fmt( "field", (StrC)field, | 				broadcast_calls.append( code_fmt( "field", (StrC)field.Name, | ||||||
| 					stringize( Event_On<field>Changed.Broadcast( GasaAttribs->Get<field>() ); ) | 					stringize( Event_On<field>Changed.Broadcast( GasaAttribs->Get<field>() ); ) | ||||||
| 				)); | 				)); | ||||||
| 			} | 			} | ||||||
| @@ -185,9 +186,9 @@ void gen_UHostWidgetController() | |||||||
| 			CodeBody bindings = def_body(ECode::Function_Body); | 			CodeBody bindings = def_body(ECode::Function_Body); | ||||||
| 			bindings.append(fmt_newline); | 			bindings.append(fmt_newline); | ||||||
| 			bindings.append(fmt_newline); | 			bindings.append(fmt_newline); | ||||||
| 			for (StringCached field : attribute_fields) | 			for (GAS_AttributeEntry field : attribute_fields) | ||||||
| 			{ | 			{ | ||||||
| 				bindings.append( code_fmt( "field", (StrC)field, | 				bindings.append( code_fmt( "field", (StrC)field.Name, | ||||||
| 				stringize( | 				stringize( | ||||||
| 					FOnGameplayAttributeValueChange& <field>AttributeChangedDelegate = AbilitySystem->GetGameplayAttributeValueChangeDelegate(GasaAttribs->Get<field>Attribute()); | 					FOnGameplayAttributeValueChange& <field>AttributeChangedDelegate = AbilitySystem->GetGameplayAttributeValueChangeDelegate(GasaAttribs->Get<field>Attribute()); | ||||||
| 					<field>AttributeChangedDelegate.AddUObject(this, &ThisClass::<field>Changed); | 					<field>AttributeChangedDelegate.AddUObject(this, &ThisClass::<field>Changed); | ||||||
| @@ -219,7 +220,7 @@ void gen_UHostWidgetController() | |||||||
|  |  | ||||||
| 			for ( s32 id = 0; id < attribute_fields.num(); ) | 			for ( s32 id = 0; id < attribute_fields.num(); ) | ||||||
| 			{ | 			{ | ||||||
| 				StringCached attribute_field = attribute_fields[id]; | 				StringCached attribute_field = attribute_fields[id].Name; | ||||||
|  |  | ||||||
| 				attribute_callbacks.append( parse_function( token_fmt( | 				attribute_callbacks.append( parse_function( token_fmt( | ||||||
| 					"field", (StrC) attribute_field, | 					"field", (StrC) attribute_field, | ||||||
|   | |||||||
| @@ -7,25 +7,44 @@ | |||||||
| #include "GasaGenCommon.cpp" | #include "GasaGenCommon.cpp" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| void def_attribute_properties                   ( CodeBody body, Array<StringCached> properties ); | struct GAS_AttributeEntry | ||||||
| void def_attribute_field_on_reps                ( CodeBody body, Array<StringCached> properties ); | { | ||||||
| void def_attribute_field_property_getters       ( CodeBody body, StrC class_name, Array<StringCached> properties ); | 	StringCached Name; | ||||||
| void def_attribute_field_value_getters          ( CodeBody body, Array<StringCached> properties ); | 	StringCached MinName; | ||||||
| void def_attribute_field_value_setters          ( CodeBody body, Array<StringCached> properties ); | 	StringCached MaxName; | ||||||
| void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, Array<StringCached> properties ); | 	float Min; | ||||||
| void def_attribute_field_initers                ( CodeBody body, Array<StringCached> properties ); | 	float Max; | ||||||
| void impl_attribute_fields                      ( CodeBody body, StrC class_name, Array<StringCached> properties ); | }; | ||||||
|  |  | ||||||
| Array<StringCached> get_gasa_attribute_fields() | void def_attribute_properties                   ( CodeBody body, Array<GAS_AttributeEntry> properties ); | ||||||
|  | void def_attribute_field_on_reps                ( CodeBody body, Array<GAS_AttributeEntry> properties ); | ||||||
|  | void def_attribute_field_property_getters       ( CodeBody body, StrC class_name, Array<GAS_AttributeEntry> properties ); | ||||||
|  | void def_attribute_field_value_getters          ( CodeBody body, Array<GAS_AttributeEntry> properties ); | ||||||
|  | void def_attribute_field_value_setters          ( CodeBody body, Array<GAS_AttributeEntry> properties ); | ||||||
|  | void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, 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 ); | ||||||
|  |  | ||||||
|  | Array<GAS_AttributeEntry> get_gasa_attribute_fields() | ||||||
| { | { | ||||||
| 	local_persist | 	local_persist | ||||||
| 	Array<StringCached> attribute_fields = Array<StringCached>::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) { | ||||||
| 		attribute_fields.append( get_cached_string(txt("Health"))); | 		StringCached str_Health    = get_cached_string(txt("Health")); | ||||||
| 		attribute_fields.append( get_cached_string(txt("MaxHealth"))); | 		StringCached str_MaxHealth = get_cached_string(txt("MaxHealth")); | ||||||
| 		attribute_fields.append( get_cached_string(txt("Mana"))); | 		StringCached str_Mana      = get_cached_string(txt("Mana")); | ||||||
| 		attribute_fields.append( get_cached_string(txt("MaxMana"))); | 		StringCached str_MaxMana   = get_cached_string(txt("MaxMana")); | ||||||
|  |  | ||||||
|  | 		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 }; | ||||||
|  |  | ||||||
|  | 		attribute_fields.append(Health); | ||||||
|  | 		attribute_fields.append(MaxHealth); | ||||||
|  | 		attribute_fields.append(Mana); | ||||||
|  | 		attribute_fields.append(MaxMana); | ||||||
| 	} | 	} | ||||||
| 	return attribute_fields; | 	return attribute_fields; | ||||||
| } | } | ||||||
| @@ -35,7 +54,7 @@ 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<StringCached> attribute_fields = get_gasa_attribute_fields(); | 	Array<GAS_AttributeEntry> attribute_fields = get_gasa_attribute_fields(); | ||||||
|  |  | ||||||
| 	StrC class_name = txt("UGasaAttributeSet"); | 	StrC class_name = txt("UGasaAttributeSet"); | ||||||
|  |  | ||||||
| @@ -57,32 +76,39 @@ void gen_UGasaAttributeSet() | |||||||
| 					body.append( UHT_GENERATED_BODY); | 					body.append( UHT_GENERATED_BODY); | ||||||
| 					body.append( access_public ); | 					body.append( access_public ); | ||||||
|  |  | ||||||
| 					def_attribute_properties( body, attribute_fields); |  | ||||||
|  |  | ||||||
| 					body.append(fmt_newline); |  | ||||||
| 					body.append( def_constructor() ); | 					body.append( def_constructor() ); | ||||||
| 					body.append(fmt_newline); | 					body.append(fmt_newline); | ||||||
|  |  | ||||||
|  | 					def_attribute_properties( body, attribute_fields); | ||||||
|  | 					body.append(fmt_newline); | ||||||
| 					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 ))); | 					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, attribute_fields ); | ||||||
| 					body.append( fmt_newline ); | 					body.append( fmt_newline ); | ||||||
| 					def_attribute_field_value_getters( body, attribute_fields ); | 					def_attribute_field_value_getters( body, attribute_fields ); | ||||||
| 					body.append( def_pragma(code( endregion Getters ))); | 					body.append( def_pragma(txt( "endregion Getters" ))); | ||||||
| 					body.append( fmt_newline ); | 					body.append( fmt_newline ); | ||||||
|  |  | ||||||
| 					body.append( def_pragma(code( region Setters ))); | 					body.append( def_pragma(txt( "region Setters" ))); | ||||||
| 					def_attribute_field_value_setters( body, attribute_fields ); | 					def_attribute_field_value_setters( body, 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, attribute_fields ); | ||||||
| 					body.append( def_pragma(code( endregion Setters ))); | 					body.append( def_pragma(txt( "endregion Setters" ))); | ||||||
| 					body.append( fmt_newline ); | 					body.append( fmt_newline ); | ||||||
|  |  | ||||||
|  | 					body.append( def_pragma( txt("region AttributeSet"))); | ||||||
|  | 					body.append( code_str( | ||||||
|  | 						void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override; | ||||||
|  | 						// void PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue) override; | ||||||
|  | 					)); | ||||||
|  | 					body.append( def_pragma( txt("endregion AttributeSet"))); | ||||||
|  | 					body.append(fmt_newline); | ||||||
|  |  | ||||||
| 					body.append( def_pragma( txt("region UObject"))); | 					body.append( def_pragma( txt("region UObject"))); | ||||||
| 					CodeFn GetLifetimeOfReplicatedProps = parse_function( code( | 					CodeFn GetLifetimeOfReplicatedProps = parse_function( code( | ||||||
| 						void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; | 						void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; | ||||||
| @@ -165,14 +191,54 @@ void gen_UGasaAttributeSet() | |||||||
|  |  | ||||||
| 			impl_attribute_fields( body, class_name, attribute_fields); | 			impl_attribute_fields( body, class_name, attribute_fields); | ||||||
|  |  | ||||||
|  | 			CodeFn PreAttributeChange; | ||||||
|  | 			{ | ||||||
|  | 				CodeBody attribute_clamps = def_body( CodeT::Function_Body ); | ||||||
|  | 				attribute_clamps.append(fmt_newline); | ||||||
|  | 				attribute_clamps.append(fmt_newline); | ||||||
|  | 				for (GAS_AttributeEntry field : attribute_fields) | ||||||
|  | 				{ | ||||||
|  | 					String clamp_min; | ||||||
|  | 					if (field.MinName.Data) | ||||||
|  | 						clamp_min = get_cached_string(token_fmt( "MinName", (StrC)field.MinName, "Get<MinName>()")); | ||||||
|  | 					else | ||||||
|  | 						clamp_min = String::fmt_buf(GlobalAllocator, "%f", field.Min); | ||||||
|  |  | ||||||
|  | 					String clamp_max; | ||||||
|  | 					if (field.MaxName.Data) | ||||||
|  | 						clamp_max = get_cached_string(token_fmt( "MaxName", (StrC)field.MaxName, "Get<MaxName>()")); | ||||||
|  | 					else | ||||||
|  | 						clamp_max = String::fmt_buf(GlobalAllocator, "%f", field.Max); | ||||||
|  |  | ||||||
|  | 					attribute_clamps.append( code_fmt( | ||||||
|  | 						"field",     (StrC)field.Name, | ||||||
|  | 						"clamp_min", (StrC)clamp_min, | ||||||
|  | 						"clamp_max", (StrC)clamp_max, | ||||||
|  | 					stringize( | ||||||
|  | 						if (Attribute == Get<field>Attribute()) | ||||||
|  | 						{ | ||||||
|  | 							NewValue = FMath::Clamp(NewValue, <clamp_min>, <clamp_max>); | ||||||
|  | 						} | ||||||
|  | 					))); | ||||||
|  | 				} | ||||||
|  | 				PreAttributeChange = parse_function( token_fmt( "attribute_clamps", (StrC)attribute_clamps.to_string(), stringize( | ||||||
|  | 					void UGasaAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) | ||||||
|  | 					{ | ||||||
|  | 						Super::PreAttributeChange(Attribute, NewValue); | ||||||
|  | 						<attribute_clamps> | ||||||
|  | 					} | ||||||
|  | 				))); | ||||||
|  | 			} | ||||||
|  | 			body.append(PreAttributeChange); | ||||||
|  |  | ||||||
| 			CodeFn GetLifetimeOfReplicatedProps; | 			CodeFn GetLifetimeOfReplicatedProps; | ||||||
| 			{ | 			{ | ||||||
| 				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 (StringCached field : attribute_fields) | 				for (GAS_AttributeEntry field : attribute_fields) | ||||||
| 				{ | 				{ | ||||||
| 					field_lifetimes.append( code_fmt( "field", (StrC)field, stringize( | 					field_lifetimes.append( code_fmt( "field", (StrC)field.Name, stringize( | ||||||
| 						DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, <field>); | 						DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, <field>); | ||||||
| 					))); | 					))); | ||||||
| 				} | 				} | ||||||
| @@ -194,44 +260,39 @@ void gen_UGasaAttributeSet() | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void def_attribute_properties( CodeBody body, Array<StringCached> properties ) | void def_attribute_properties( CodeBody body, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	for ( StringCached property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		Code field_uproperty = code_fmt( "property", (StrC)property, stringize( | 		Code field_uproperty = code_fmt( "property", (StrC)property.Name, stringize( | ||||||
| 			UPROPERTY(ReplicatedUsing=Client_OnRep_<property>, EditAnywhere, BlueprintReadWrite, Category="Attributes") | 			UPROPERTY(ReplicatedUsing=Client_OnRep_<property>, EditAnywhere, BlueprintReadWrite, Category="Attributes") | ||||||
|  | 			FGameplayAttributeData <property>; | ||||||
| 		)); | 		)); | ||||||
|  | 		body.append(field_uproperty); | ||||||
| 		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(property)) ); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void def_attribute_field_on_reps( CodeBody body, Array<StringCached> properties ) | void def_attribute_field_on_reps( CodeBody body, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	for ( StringCached property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		Code umeta_UFUNCTION = code_str( UFUNCTION() ); | 		Code umeta_UFUNCTION = code_str( UFUNCTION() ); | ||||||
|  |  | ||||||
| 		body.append(fmt_newline); | 		body.append(fmt_newline); | ||||||
| 		body.append( umeta_UFUNCTION ); | 		body.append( umeta_UFUNCTION ); | ||||||
| 		body.append(fmt_newline); | 		body.append(fmt_newline); | ||||||
| 		body.append( code_fmt( "property", (StrC)property, stringize( | 		body.append( code_fmt( "property", (StrC)property.Name, stringize( | ||||||
| 			void Client_OnRep_<property>(FGameplayAttributeData& Prev<property>); | 			void Client_OnRep_<property>(FGameplayAttributeData& Prev<property>); | ||||||
| 		))); | 		))); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array<StringCached> properties ) | void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	for ( String property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		CodeFn generated_get_attribute = parse_function( | 		CodeFn generated_get_attribute = parse_function( | ||||||
| 			token_fmt( "class_name", class_name, "property", (StrC)property, | 			token_fmt( "class_name", class_name, "property", (StrC)property.Name, | ||||||
| 			stringize( | 			stringize( | ||||||
| 				static FGameplayAttribute Get<property>Attribute() | 				static FGameplayAttribute Get<property>Attribute() | ||||||
| 				{ | 				{ | ||||||
| @@ -245,11 +306,11 @@ void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array | |||||||
|  |  | ||||||
| #pragma push_macro("FORCEINLINE") | #pragma push_macro("FORCEINLINE") | ||||||
| #undef FORCEINLINE | #undef FORCEINLINE | ||||||
| void def_attribute_field_value_getters( CodeBody body, Array<StringCached> properties ) | void def_attribute_field_value_getters( CodeBody body, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	for ( String property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		body.append( code_fmt( "property", (StrC)property, | 		body.append( code_fmt( "property", (StrC)property.Name, | ||||||
| 		stringize( | 		stringize( | ||||||
| 			FORCEINLINE float Get<property>() const | 			FORCEINLINE float Get<property>() const | ||||||
| 			{ | 			{ | ||||||
| @@ -259,24 +320,24 @@ void def_attribute_field_value_getters( CodeBody body, Array<StringCached> prope | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void def_attribute_field_value_setters( CodeBody body, Array<StringCached> properties ) | void def_attribute_field_value_setters( CodeBody body, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	for ( String property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		body.append( code_fmt( "property", (StrC)property, | 		body.append( code_fmt( "property", (StrC)property.Name, | ||||||
| 		stringize( | 		stringize( | ||||||
| 			FORCEINLINE void Set<property>(float NewVal); | 			FORCEINLINE void Set<property>(float NewVal); | ||||||
| 		))); | 		))); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, Array<StringCached> properties ) | void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	body.append(def_pragma( txt("region Attribute Setters"))); | 	body.append(def_pragma( txt("region Attribute Setters"))); | ||||||
| 	for ( String property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		CodeFn generated_get_attribute = parse_function( | 		CodeFn generated_get_attribute = parse_function( | ||||||
| 			token_fmt( "class_name", class_name, "property", (StrC)property, | 			token_fmt( "class_name", class_name, "property", (StrC)property.Name, | ||||||
| 			stringize( | 			stringize( | ||||||
| 				FORCEINLINE void <class_name>::Set<property>(float NewVal) | 				FORCEINLINE void <class_name>::Set<property>(float NewVal) | ||||||
| 				{ | 				{ | ||||||
| @@ -292,11 +353,11 @@ void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name | |||||||
| 	body.append(def_pragma( txt("endregion Attribute Setters"))); | 	body.append(def_pragma( txt("endregion Attribute Setters"))); | ||||||
| } | } | ||||||
|  |  | ||||||
| void def_attribute_field_initers ( CodeBody body, Array<StringCached> properties ) | void def_attribute_field_initers ( CodeBody body, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	for ( String property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		body.append( code_fmt( "property", (StrC)property, | 		body.append( code_fmt( "property", (StrC)property.Name, | ||||||
| 		stringize( | 		stringize( | ||||||
| 			FORCEINLINE void Init<property>(float NewVal) | 			FORCEINLINE void Init<property>(float NewVal) | ||||||
| 			{ | 			{ | ||||||
| @@ -307,14 +368,14 @@ void def_attribute_field_initers ( CodeBody body, Array<StringCached> properties | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void impl_attribute_fields( CodeBody body, StrC class_name, Array<StringCached> properties ) | void impl_attribute_fields( CodeBody body, StrC class_name, Array<GAS_AttributeEntry> properties ) | ||||||
| { | { | ||||||
| 	body.append(fmt_newline); | 	body.append(fmt_newline); | ||||||
| 	body.append(def_pragma( txt("region Rep Notifies"))); | 	body.append(def_pragma( txt("region Rep Notifies"))); | ||||||
| 	for ( String property : properties ) | 	for ( GAS_AttributeEntry property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		CodeFn field_impl = parse_function( token_fmt( | 		CodeFn field_impl = parse_function( token_fmt( | ||||||
| 			"class_name", class_name, "property", (StrC)property, "from_notice", txt("\n// From GAMEPLAYATTRIBUTE_REPNOTIFY\n"), | 			"class_name", class_name, "property", (StrC)property.Name, "from_notice", txt("\n// From GAMEPLAYATTRIBUTE_REPNOTIFY\n"), | ||||||
| 		stringize( | 		stringize( | ||||||
| 			void <class_name>::Client_OnRep_<property>(FGameplayAttributeData& Prev<property>) | 			void <class_name>::Client_OnRep_<property>(FGameplayAttributeData& Prev<property>) | ||||||
| 			{ | 			{ | ||||||
|   | |||||||
| @@ -55,6 +55,21 @@ | |||||||
| 		</Expand> | 		</Expand> | ||||||
| 	</Type> | 	</Type> | ||||||
|  |  | ||||||
|  | 	<Type Name="gen::StringCached"> | ||||||
|  | 		<DisplayString Condition="Data == nullptr">null</DisplayString> | ||||||
|  | 		<DisplayString>{Data,na}</DisplayString> | ||||||
|  | 		<Expand> | ||||||
|  | 			<Synthetic Name="Header"> | ||||||
|  | 				<DisplayString>{(Header*)((char*)Data - sizeof(Header))}</DisplayString> | ||||||
|  | 				<Expand> | ||||||
|  | 					<Item Name="Allocator">((Header*)((char*)Data - sizeof(Header)))->Allocator</Item> | ||||||
|  | 					<Item Name="Capacity">((Header*)((char*)Data - sizeof(Header)))->Capacity</Item> | ||||||
|  | 					<Item Name="Length">((Header*)((char*)Data - sizeof(Header)))->Length</Item> | ||||||
|  | 				</Expand> | ||||||
|  | 			</Synthetic> | ||||||
|  | 		</Expand> | ||||||
|  | 	</Type> | ||||||
|  |  | ||||||
| 	<Type Name="gen::String::Header"> | 	<Type Name="gen::String::Header"> | ||||||
| 		<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString> | 		<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString> | ||||||
| 		<Expand> | 		<Expand> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user