37. Effect Actor Improved
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-Gasa.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-Gasa.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -130,7 +130,3 @@ ManualIPAddress= | |||||||
| +CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic") | +CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic") | ||||||
| +CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle") | +CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle") | ||||||
| +CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn") | +CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn") | ||||||
|  |  | ||||||
|  |  | ||||||
| [CoreRedirects] |  | ||||||
| +ClassRedirects=(OldName="/Script/Gasa.UI_HostWidget",NewName="/Script/Gasa.HUDHostWidget") |  | ||||||
| @@ -1,6 +1,8 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "GasaAbilitySystemComponent.h" | #include "GasaAbilitySystemComponent.h" | ||||||
| #include "AbilitySystemInterface.h" | #include "AbilitySystemInterface.h" | ||||||
|  | #include "AbilitySystemGlobals.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace Gasa | namespace Gasa | ||||||
| { | { | ||||||
| @@ -13,4 +15,24 @@ namespace Gasa | |||||||
| 		} | 		} | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// From: UAbilitySystemGlobals::GetAbilitySystemComponentFromActor | ||||||
|  | 	inline | ||||||
|  | 	UGasaAbilitySystemComp* GetAbilitySystem(AActor* Actor, bool LookForComponent = false) | ||||||
|  | 	{ | ||||||
|  | 		if (Actor == nullptr) | ||||||
|  | 			return nullptr; | ||||||
|  |  | ||||||
|  | 		const IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(Actor); | ||||||
|  | 		if (ASI) | ||||||
|  | 			return Cast<UGasaAbilitySystemComp>(ASI->GetAbilitySystemComponent()); | ||||||
|  |  | ||||||
|  | 		if (LookForComponent) | ||||||
|  | 		{ | ||||||
|  | 			// Fall back to a component search to better support BP-only actors | ||||||
|  | 			return Cast<UGasaAbilitySystemComp>(Actor->FindComponentByClass<UAbilitySystemComponent>()); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return nullptr; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,29 +10,39 @@ UGasaAttributeSet::UGasaAttributeSet() | |||||||
| { | { | ||||||
| 	InitHealth( 50.f ); | 	InitHealth( 50.f ); | ||||||
| 	InitMaxHealth( 100.f ); | 	InitMaxHealth( 100.f ); | ||||||
| 	InitMana( 25.f ); | 	InitMana( 50.f ); | ||||||
| 	InitMaxMana( 50.f ); | 	InitMaxMana( 50.f ); | ||||||
| } | } | ||||||
|  | #pragma region Rep Notifies | ||||||
|  |  | ||||||
| void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth ) | void UGasaAttributeSet::Client_OnRep_Health( FGameplayAttributeData& PrevHealth ) | ||||||
| { | { | ||||||
| 	GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, Health, PrevHealth ) | 	// From GAMEPLAYATTRIBUTE_REPNOTIFY | ||||||
|  | 	static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Health ) ); | ||||||
|  | 	GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Health, PrevHealth ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void UGasaAttributeSet::Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth ) | void UGasaAttributeSet::Client_OnRep_MaxHealth( FGameplayAttributeData& PrevMaxHealth ) | ||||||
| { | { | ||||||
| 	GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, MaxHealth, PrevMaxHealth ) | 	// From GAMEPLAYATTRIBUTE_REPNOTIFY | ||||||
|  | 	static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxHealth ) ); | ||||||
|  | 	GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxHealth, PrevMaxHealth ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void UGasaAttributeSet::Client_OnRep_Mana( FGameplayAttributeData& PrevMana ) | void UGasaAttributeSet::Client_OnRep_Mana( FGameplayAttributeData& PrevMana ) | ||||||
| { | { | ||||||
| 	GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, Mana, PrevMana ) | 	// From GAMEPLAYATTRIBUTE_REPNOTIFY | ||||||
|  | 	static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, Mana ) ); | ||||||
|  | 	GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), Mana, PrevMana ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana ) | void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMana ) | ||||||
| { | { | ||||||
| 	GAMEPLAYATTRIBUTE_REPNOTIFY( UGasaAttributeSet, MaxMana, PrevMaxMana ) | 	// From GAMEPLAYATTRIBUTE_REPNOTIFY | ||||||
|  | 	static FProperty* UGasaAttributeSetProperty = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) ); | ||||||
|  | 	GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxMana, PrevMaxMana ); | ||||||
| } | } | ||||||
|  | #pragma endregion Rep Notifies | ||||||
| void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const | void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const | ||||||
| { | { | ||||||
| 	Super::GetLifetimeReplicatedProps( OutLifetimeProps ); | 	Super::GetLifetimeReplicatedProps( OutLifetimeProps ); | ||||||
|   | |||||||
| @@ -1,61 +1,23 @@ | |||||||
| #include "GasaEffectActor.h" | #include "GasaEffectActor.h" | ||||||
|  |  | ||||||
| #include "AbilitySystemInterface.h" | #include "GasaAbilitySystemComponent_Inlines.h" | ||||||
| #include "GasaAttributeSet.h" | using namespace Gasa; | ||||||
| #include "GasaAttributeSet_Inlines.h" |  | ||||||
| #include "Components/SphereComponent.h" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| AGasaEffectActor::AGasaEffectActor() | AGasaEffectActor::AGasaEffectActor() | ||||||
| { | { | ||||||
| 	PrimaryActorTick.bCanEverTick = false; | 	PrimaryActorTick.bCanEverTick = false; | ||||||
|  |  | ||||||
| 	Mesh   = CreateDefaultSubobject<UStaticMeshComponent>("Mesh"); | 	RootComponent = CreateDefaultSubobject<USceneComponent>("Root"); | ||||||
| 	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere"); |  | ||||||
|  |  | ||||||
| 	SetRootComponent(Mesh); |  | ||||||
| 	Sphere->SetupAttachment(Mesh); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void AGasaEffectActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent | void AGasaEffectActor::ApplyEffectToTarget(AActor* Target, TSubclassOf<UGameplayEffect> EffectClass) | ||||||
| 	, AActor* OtherActor |  | ||||||
| 	, UPrimitiveComponent* OtherComp |  | ||||||
| 	, int32 OtherBodyIndex |  | ||||||
| 	, bool bFromSweep |  | ||||||
| 	, FHitResult const& SweepResult) |  | ||||||
| { | { | ||||||
| 	// Demo of "restricted way" | 	UGasaAbilitySystemComp* AS = GetAbilitySystem(Target, true); | ||||||
| 	if ( ! OtherActor->Implements<UAbilitySystemInterface>()) |  | ||||||
| 		return; | 	FGameplayEffectContextHandle | ||||||
|  | 	Context = AS->MakeEffectContext(); | ||||||
|  | 	Context.AddSourceObject(Target); | ||||||
| 	 | 	 | ||||||
| 	IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(OtherActor); | 	FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context ); | ||||||
| 	if (ASI == nullptr) | 	AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	// TODO(Ed): Change this to use a gameplay effect instead |  | ||||||
| 	UAbilitySystemComponent* AbilitySystem = ASI->GetAbilitySystemComponent(); |  | ||||||
| 	UGasaAttributeSet*       MutAttributes = const_cast<UGasaAttributeSet*>(Gasa::GetAttributeSet(AbilitySystem)); |  | ||||||
| 	 |  | ||||||
| 	MutAttributes->SetHealth( MutAttributes->GetHealth() + 25.f ); |  | ||||||
| 	Destroy(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AGasaEffectActor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent |  | ||||||
| 	, AActor* OtherActor |  | ||||||
| 	, UPrimitiveComponent* OtherComp |  | ||||||
| 	, int32 OtherBodyIndex) |  | ||||||
| { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AGasaEffectActor::BeginPlay() |  | ||||||
| { |  | ||||||
| 	Super::BeginPlay(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AGasaEffectActor::PostInitializeComponents() |  | ||||||
| { |  | ||||||
| 	Super::PostInitializeComponents(); |  | ||||||
|  |  | ||||||
| 	Sphere->OnComponentBeginOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapBegin); |  | ||||||
| 	Sphere->OnComponentEndOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapEnd); |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,39 +1,19 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "GasaCommon.h" | #include "GasaCommon.h" | ||||||
|  |  | ||||||
| #include "GasaEffectActor.generated.h" | #include "GasaEffectActor.generated.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| UCLASS() | UCLASS() | ||||||
| class GASA_API AGasaEffectActor : public AActor | class GASA_API AGasaEffectActor : public AActor | ||||||
| { | { | ||||||
| 	GENERATED_BODY() | 	GENERATED_BODY() | ||||||
| public: | public: | ||||||
|  |  | ||||||
| 	UPROPERTY(VisibleAnywhere) | 	UPROPERTY(EditAnywhere, Category = "Applied Effects") | ||||||
| 	TObjectPtr<UStaticMeshComponent> Mesh; | 	TSoftClassPtr<UGameplayEffect> InstantEffectClass; | ||||||
| 	UPROPERTY(VisibleAnywhere) |  | ||||||
| 	TObjectPtr<USphereComponent> Sphere; |  | ||||||
| 	 | 	 | ||||||
| 	AGasaEffectActor(); | 	AGasaEffectActor(); | ||||||
|  |  | ||||||
| 	UFUNCTION() | 	void ApplyEffectToTarget(AActor* Target, TSubclassOf<UGameplayEffect> EffectClass ); | ||||||
| 	void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent |  | ||||||
| 		, AActor*              OtherActor |  | ||||||
| 		, UPrimitiveComponent* OtherComp |  | ||||||
| 		, int32                OtherBodyIndex |  | ||||||
| 		, bool                 bFromSweep |  | ||||||
| 		, FHitResult const&    SweepResult); |  | ||||||
|  |  | ||||||
| 	UFUNCTION() |  | ||||||
| 	void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent |  | ||||||
| 		, AActor*                          OtherActor |  | ||||||
| 		, UPrimitiveComponent*             OtherComp |  | ||||||
| 		, int32                            OtherBodyIndex); |  | ||||||
| 	 |  | ||||||
| #pragma region Actor |  | ||||||
| 	void BeginPlay() override; |  | ||||||
| 	 |  | ||||||
| 	void PostInitializeComponents() override; |  | ||||||
| #pragma endregion Actor |  | ||||||
| }; | }; | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | #include "GasaEffectActorDemo.h" | ||||||
|  |  | ||||||
|  | #include "AbilitySystemInterface.h" | ||||||
|  | #include "GasaAttributeSet.h" | ||||||
|  | #include "GasaAttributeSet_Inlines.h" | ||||||
|  | #include "Components/SphereComponent.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AGasaEffectActorDemo::AGasaEffectActorDemo() | ||||||
|  | { | ||||||
|  | 	PrimaryActorTick.bCanEverTick = false; | ||||||
|  |  | ||||||
|  | 	Mesh   = CreateDefaultSubobject<UStaticMeshComponent>("Mesh"); | ||||||
|  | 	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere"); | ||||||
|  |  | ||||||
|  | 	SetRootComponent(Mesh); | ||||||
|  | 	Sphere->SetupAttachment(Mesh); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void AGasaEffectActorDemo::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent | ||||||
|  | 	, AActor* OtherActor | ||||||
|  | 	, UPrimitiveComponent* OtherComp | ||||||
|  | 	, int32 OtherBodyIndex | ||||||
|  | 	, bool bFromSweep | ||||||
|  | 	, FHitResult const& SweepResult) | ||||||
|  | { | ||||||
|  | 	// Demo of "restricted way" | ||||||
|  | 	if ( ! OtherActor->Implements<UAbilitySystemInterface>()) | ||||||
|  | 		return; | ||||||
|  | 	 | ||||||
|  | 	IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(OtherActor); | ||||||
|  | 	if (ASI == nullptr) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	// TODO(Ed): Change this to use a gameplay effect instead | ||||||
|  | 	UAbilitySystemComponent* AbilitySystem = ASI->GetAbilitySystemComponent(); | ||||||
|  | 	UGasaAttributeSet*       MutAttributes = const_cast<UGasaAttributeSet*>(Gasa::GetAttributeSet(AbilitySystem)); | ||||||
|  | 	 | ||||||
|  | 	MutAttributes->SetHealth( MutAttributes->GetHealth() + 25.f ); | ||||||
|  | 	MutAttributes->SetMana( MutAttributes->GetMana() - 25.f ); | ||||||
|  | 	Destroy(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void AGasaEffectActorDemo::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent | ||||||
|  | 	, AActor* OtherActor | ||||||
|  | 	, UPrimitiveComponent* OtherComp | ||||||
|  | 	, int32 OtherBodyIndex) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void AGasaEffectActorDemo::BeginPlay() | ||||||
|  | { | ||||||
|  | 	Super::BeginPlay(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void AGasaEffectActorDemo::PostInitializeComponents() | ||||||
|  | { | ||||||
|  | 	Super::PostInitializeComponents(); | ||||||
|  |  | ||||||
|  | 	Sphere->OnComponentBeginOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapBegin); | ||||||
|  | 	Sphere->OnComponentEndOverlap.AddUniqueDynamic(this, &ThisClass::OnOverlapEnd); | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "GasaCommon.h" | ||||||
|  |  | ||||||
|  | #include "GasaEffectActorDemo.generated.h" | ||||||
|  |  | ||||||
|  | // Old demonstration code used before part 37. | ||||||
|  | UCLASS() | ||||||
|  | class GASA_API AGasaEffectActorDemo : public AActor | ||||||
|  | { | ||||||
|  | 	GENERATED_BODY() | ||||||
|  | public: | ||||||
|  |  | ||||||
|  | 	UPROPERTY(VisibleAnywhere) | ||||||
|  | 	TObjectPtr<UStaticMeshComponent> Mesh; | ||||||
|  | 	UPROPERTY(VisibleAnywhere) | ||||||
|  | 	TObjectPtr<USphereComponent> Sphere; | ||||||
|  | 	 | ||||||
|  | 	AGasaEffectActorDemo(); | ||||||
|  |  | ||||||
|  | 	UFUNCTION() | ||||||
|  | 	void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent | ||||||
|  | 		, AActor*              OtherActor | ||||||
|  | 		, UPrimitiveComponent* OtherComp | ||||||
|  | 		, int32                OtherBodyIndex | ||||||
|  | 		, bool                 bFromSweep | ||||||
|  | 		, FHitResult const&    SweepResult); | ||||||
|  |  | ||||||
|  | 	UFUNCTION() | ||||||
|  | 	void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent | ||||||
|  | 		, AActor*                          OtherActor | ||||||
|  | 		, UPrimitiveComponent*             OtherComp | ||||||
|  | 		, int32                            OtherBodyIndex); | ||||||
|  | 	 | ||||||
|  | #pragma region Actor | ||||||
|  | 	void BeginPlay() override; | ||||||
|  | 	 | ||||||
|  | 	void PostInitializeComponents() override; | ||||||
|  | #pragma endregion Actor | ||||||
|  | }; | ||||||
| @@ -22,6 +22,7 @@ class UAbilitySystemComponent; | |||||||
| class UAbilitySystemInterface; | class UAbilitySystemInterface; | ||||||
| class UAttributeSet; | class UAttributeSet; | ||||||
| class UCameraComponent; | class UCameraComponent; | ||||||
|  | class UGameplayEffect; | ||||||
| class UInputAction; | class UInputAction; | ||||||
| class UInputMappingContext; | class UInputMappingContext; | ||||||
| class USphereComponent; | class USphereComponent; | ||||||
|   | |||||||
| @@ -29,6 +29,8 @@ void UHostWidgetController::MaxManaChanged( FOnAttributeChangeData const& Attrib | |||||||
|  |  | ||||||
| void UHostWidgetController::BroadcastInitialValues() | void UHostWidgetController::BroadcastInitialValues() | ||||||
| { | { | ||||||
|  | 	// This function is managed by: GenGasa/GenGasa_HostWidgetController.cpp | ||||||
|  |  | ||||||
| 	UGasaAttributeSet* GasaAttribs = Cast<UGasaAttributeSet>( Data.Attributes ); | 	UGasaAttributeSet* GasaAttribs = Cast<UGasaAttributeSet>( Data.Attributes ); | ||||||
| 	if ( GasaAttribs ) | 	if ( GasaAttribs ) | ||||||
| 	{ | 	{ | ||||||
| @@ -37,10 +39,13 @@ void UHostWidgetController::BroadcastInitialValues() | |||||||
| 		Event_OnManaChanged.Broadcast( GasaAttribs->GetMana() ); | 		Event_OnManaChanged.Broadcast( GasaAttribs->GetMana() ); | ||||||
| 		Event_OnMaxManaChanged.Broadcast( GasaAttribs->GetMaxMana() ); | 		Event_OnMaxManaChanged.Broadcast( GasaAttribs->GetMaxMana() ); | ||||||
| 	} | 	} | ||||||
|  | 	BindCallbacksToDependencies(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void UHostWidgetController::BindCallbacksToDependencies() | void UHostWidgetController::BindCallbacksToDependencies() | ||||||
| { | { | ||||||
|  | 	// This function is managed by: GenGasa/GenGasa_HostWidgetController.cpp | ||||||
|  |  | ||||||
| 	UGasaAbilitySystemComp* AbilitySystem = Cast<UGasaAbilitySystemComp>( Data.AbilitySystem ); | 	UGasaAbilitySystemComp* AbilitySystem = Cast<UGasaAbilitySystemComp>( Data.AbilitySystem ); | ||||||
| 	UGasaAttributeSet*      GasaAttribs   = Cast<UGasaAttributeSet>( Data.Attributes ); | 	UGasaAttributeSet*      GasaAttribs   = Cast<UGasaAttributeSet>( Data.Attributes ); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -301,4 +301,4 @@ void gen_UHostWidgetController() | |||||||
| 		source.write(); | 		source.write(); | ||||||
| 		format_file(path_gasa_ui "HostWidgetController.cpp"); | 		format_file(path_gasa_ui "HostWidgetController.cpp"); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -307,19 +307,37 @@ 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<StringCached> properties ) | ||||||
| { | { | ||||||
|  | 	body.append(def_pragma( txt("region Rep Notifies"))); | ||||||
| 	for ( String property : properties ) | 	for ( String property : properties ) | ||||||
| 	{ | 	{ | ||||||
| 		body.append(fmt_newline); | 		body.append(fmt_newline); | ||||||
|  |  | ||||||
| 		CodeFn field_impl = parse_function( token_fmt( "class_name", class_name, "property", (StrC)property, | 		CodeFn field_impl = parse_function( token_fmt( | ||||||
|  | 			"class_name", class_name, "property", (StrC)property, "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>) | ||||||
| 			{ | 			{ | ||||||
| 				GAMEPLAYATTRIBUTE_REPNOTIFY(<class_name>, <property>, Prev<property>) | 				<from_notice> | ||||||
|  | 				static FProperty* <class_name>Property = FindFieldChecked<FProperty>( StaticClass(), GET_MEMBER_NAME_CHECKED(<class_name>, <property>)); | ||||||
|  | 				GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(<class_name>Property), <property>, Prev<property>); | ||||||
| 			} | 			} | ||||||
| 		))); | 		))); | ||||||
|  |  | ||||||
| 		body.append( field_impl ); | 		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* <class_name>Property = FindFieldChecked<FProperty>(<class_name>::StaticClass(), GET_MEMBER_NAME_CHECKED(<class_name>, <property_name>)); | ||||||
|  | 		GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication(FGameplayAttribute(<class_name>Property), <property_name>, <old_value>); | ||||||
|  | 	)); | ||||||
| } | } | ||||||
| #pragma pop_macro("FORCEINLINE") | #pragma pop_macro("FORCEINLINE") | ||||||
|   | |||||||
| @@ -8635,18 +8635,18 @@ namespace parser | |||||||
| 		result->Type    = Function_Body; | 		result->Type    = Function_Body; | ||||||
|  |  | ||||||
| 		// TODO : Support actual parsing of function body | 		// TODO : Support actual parsing of function body | ||||||
| 		Token start = currtok; | 		Token start = currtok_noskip; | ||||||
|  |  | ||||||
| 		s32 level   = 0; | 		s32 level   = 0; | ||||||
| 		while ( left && ( currtok.Type != TokType::BraceCurly_Close || level > 0 ) ) | 		while ( left && ( currtok_noskip.Type != TokType::BraceCurly_Close || level > 0 ) ) | ||||||
| 		{ | 		{ | ||||||
| 			if ( currtok.Type == TokType::BraceCurly_Open ) | 			if ( currtok_noskip.Type == TokType::BraceCurly_Open ) | ||||||
| 				level++; | 				level++; | ||||||
|  |  | ||||||
| 			else if ( currtok.Type == TokType::BraceCurly_Close && level > 0 ) | 			else if ( currtok_noskip.Type == TokType::BraceCurly_Close && level > 0 ) | ||||||
| 				level--; | 				level--; | ||||||
|  |  | ||||||
| 			eat( currtok.Type ); | 			eat( currtok_noskip.Type ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Token previous = prevtok; | 		Token previous = prevtok; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user