// Used in the GasaGen.cpp translation unit #if GASA_INTELLISENSE_DIRECTIVES #pragma once #define GEN_EXPOSE_BACKEND #include "gen.hpp" #include "gen.builder.hpp" #include "GasaGenCommon.cpp" #endif void def_attribute_properties ( CodeBody body, Array properties ); void def_attribute_field_on_reps ( CodeBody body, Array properties ); void def_attribute_field_property_getters ( CodeBody body, StrC class_name, Array properties ); void def_attribute_field_value_getters ( CodeBody body, Array properties ); void def_attribute_field_value_setters ( CodeBody body, Array properties ); void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, Array properties ); void def_attribute_field_initers ( CodeBody body, Array properties ); void impl_attribute_fields ( CodeBody body, StrC class_name, Array properties ); Array get_gasa_attribute_fields() { local_persist Array attribute_fields = Array::init_reserve(GlobalAllocator, 64); for (local_persist s32 do_once = 0; do_once == 0; ++ do_once) { attribute_fields.append( get_cached_string(txt("Health"))); attribute_fields.append( get_cached_string(txt("MaxHealth"))); attribute_fields.append( get_cached_string(txt("Mana"))); attribute_fields.append( get_cached_string(txt("MaxMana"))); } return attribute_fields; } void gen_UGasaAttributeSet() { CodeType type_UAttributeSet = def_type( txt("UAttributeSet") ); CodeComment generation_notice = def_comment(txt("Generated by GasaGen/GasaGen_UGasaAttributeSet.cpp")); Array attribute_fields = get_gasa_attribute_fields(); StrC class_name = txt("UGasaAttributeSet"); Builder header = Builder::open( path_gasa_ability_system "GasaAttributeSet.h"); { header.print(generation_notice); header.print(pragma_once); header.print(fmt_newline); { CodeInclude Include_AttributeSet = def_include(txt("AttributeSet.h")); CodeInclude Include_GasaAttributeSet_Generated = def_include(txt("GasaAttributeSet.generated.h")); CodeAttributes api_attribute= def_attributes( UModule_GASA_API->Name); CodeClass GasaAttributeSet = {}; { CodeBody body = def_body( CodeT::Class_Body ); { body.append( UHT_GENERATED_BODY); body.append( access_public ); def_attribute_properties( body, attribute_fields); body.append(fmt_newline); body.append( def_constructor() ); body.append(fmt_newline); def_attribute_field_on_reps( body, attribute_fields); body.append(fmt_newline); body.append( fmt_newline ); body.append( def_pragma(code( region Getters ))); def_attribute_field_property_getters( body, class_name, attribute_fields ); body.append( fmt_newline ); 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 ); body.append( fmt_newline ); body.append( fmt_newline ); 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"))); CodeFn GetLifetimeOfReplicatedProps = parse_function( code( void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; )); body.append( GetLifetimeOfReplicatedProps ); body.append( def_pragma( txt("endregion UObject"))); } GasaAttributeSet = def_class( class_name, body , type_UAttributeSet, AccessSpec::Public , api_attribute ); } header.print( Include_AttributeSet); header.print( Include_GasaAttributeSet_Generated); header.print( fmt_newline); header.print( UHT_UCLASS ); header.print(GasaAttributeSet); } header.write(); format_file(path_gasa_ability_system "GasaAttributeSet.h"); } Builder inlines = Builder::open( path_gasa_ability_system "GasaAttributeSet_Inlines.h"); { inlines.print(generation_notice); inlines.print(pragma_once); inlines.print(fmt_newline); inlines.print( def_include( txt("GasaAttributeSet.h"))); inlines.print( def_include(txt("AbilitySystemComponent.h"))); inlines.print(fmt_newline); CodeBody body = def_body(CodeT::Global_Body); { def_attribute_field_property_setter_inlines( body, class_name, attribute_fields ); } inlines.print(body); inlines.print(fmt_newline); CodeNS ns_gasa = parse_namespace( code( namespace Gasa { inline UGasaAttributeSet const* GetAttributeSet( UAbilitySystemComponent* ASC ) { return Cast(ASC->GetAttributeSet( UGasaAttributeSet::StaticClass() )); } } )); inlines.print(ns_gasa); inlines.write(); format_file(path_gasa_ability_system "GasaAttributeSet_Inlines.h"); } Builder source = Builder::open( path_gasa_ability_system "GasaAttributeSet.cpp" ); { source.print(generation_notice); header.print(fmt_newline); source.print( def_include( txt("GasaAttributeSet.h"))); source.print( def_include( txt("GasaAttributeSet_Inlines.h"))); source.print(fmt_newline); source.print( def_include( txt("AbilitySystemComponent.h"))); source.print( def_include( txt("Net/UnrealNetwork.h"))); source.print( def_include( txt("Networking/GasaNetLibrary.h"))); { CodeBody body = def_body( CodeT::Global_Body ); body.append(fmt_newline); CodeConstructor constructor_for_UGasaAttributeSet = parse_constructor( code( UGasaAttributeSet::UGasaAttributeSet() { InitHealth( 100.f ); InitMaxHealth( 100.f ); InitMana( 50.f ); InitMaxMana( 50.f ); } )); body.append(constructor_for_UGasaAttributeSet ); impl_attribute_fields( body, class_name, attribute_fields); CodeFn GetLifetimeOfReplicatedProps; { CodeBody field_lifetimes = def_body( CodeT::Function_Body); field_lifetimes.append(fmt_newline); field_lifetimes.append(fmt_newline); for (StringCached field : attribute_fields) { field_lifetimes.append( code_fmt( "field", (StrC)field, stringize( DOREPLIFETIME_DEFAULT_GAS(UGasaAttributeSet, ); ))); } GetLifetimeOfReplicatedProps = parse_function( token_fmt( "field_lifetimes", (StrC)(field_lifetimes.to_string()), stringize( void UGasaAttributeSet::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); } ))); } body.append(GetLifetimeOfReplicatedProps); source.print(body); } source.write(); format_file(path_gasa_ability_system "GasaAttributeSet.cpp"); } } void def_attribute_properties( CodeBody body, Array properties ) { for ( StringCached property : properties ) { 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(property)) ); } } void def_attribute_field_on_reps( CodeBody body, Array properties ) { for ( StringCached property : properties ) { Code umeta_UFUNCTION = code_str( UFUNCTION() ); body.append(fmt_newline); body.append( umeta_UFUNCTION ); body.append(fmt_newline); body.append( code_fmt( "property", (StrC)property, stringize( void Client_OnRep_(FGameplayAttributeData& Prev); ))); } } void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array properties ) { for ( String property : properties ) { 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 ); } } #pragma push_macro("FORCEINLINE") #undef FORCEINLINE void def_attribute_field_value_getters( CodeBody body, Array properties ) { for ( String property : properties ) { body.append( code_fmt( "property", (StrC)property, stringize( FORCEINLINE float Get() const { return .GetCurrentValue(); } ))); } } 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); ))); } } void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, Array properties ) { for ( String property : properties ) { CodeFn generated_get_attribute = parse_function( token_fmt( "class_name", class_name, "property", (StrC)property, stringize( FORCEINLINE void ::Set(float NewVal) { UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent(); if (ensure(AbilityComp)) { AbilityComp->SetNumericAttributeBase(GetAttribute(), NewVal); }; } ))); body.append( generated_get_attribute ); } } 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 ) { body.append(def_pragma( txt("region Rep Notifies"))); for ( String property : properties ) { body.append(fmt_newline); CodeFn field_impl = parse_function( token_fmt( "class_name", class_name, "property", (StrC)property, "from_notice", txt("\n// From GAMEPLAYATTRIBUTE_REPNOTIFY\n"), stringize( void ::Client_OnRep_(FGameplayAttributeData& Prev) { static FProperty* Property = FindFieldChecked( StaticClass(), GET_MEMBER_NAME_CHECKED(, )); GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(Property), , Prev); } ))); body.append( field_impl ); } body.append( def_pragma( txt("endregion Rep Notifies"))); } inline Code gen_GAMEPLAYATTRIBUTE_REPNOTIFY(StrC class_name, StrC property_name, StrC old_value) { Code rep_notify = code_fmt( "class_name", class_name , "property_name", property_name , "old_value", old_value, stringize( static FProperty* Property = FindFieldChecked(::StaticClass(), GET_MEMBER_NAME_CHECKED(, )); GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(Property), , ); )); } #pragma pop_macro("FORCEINLINE")