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="VehicleMovement",NewName="Vehicle")
 | 
			
		||||
+CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[CoreRedirects]
 | 
			
		||||
+ClassRedirects=(OldName="/Script/Gasa.UI_HostWidget",NewName="/Script/Gasa.HUDHostWidget")
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "GasaAbilitySystemComponent.h"
 | 
			
		||||
#include "AbilitySystemInterface.h"
 | 
			
		||||
#include "AbilitySystemGlobals.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Gasa
 | 
			
		||||
{
 | 
			
		||||
@@ -13,4 +15,24 @@ namespace Gasa
 | 
			
		||||
		}
 | 
			
		||||
		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 );
 | 
			
		||||
	InitMaxHealth( 100.f );
 | 
			
		||||
	InitMana( 25.f );
 | 
			
		||||
	InitMana( 50.f );
 | 
			
		||||
	InitMaxMana( 50.f );
 | 
			
		||||
}
 | 
			
		||||
#pragma region Rep Notifies
 | 
			
		||||
 | 
			
		||||
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 )
 | 
			
		||||
{
 | 
			
		||||
	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 )
 | 
			
		||||
{
 | 
			
		||||
	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 )
 | 
			
		||||
{
 | 
			
		||||
	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
 | 
			
		||||
{
 | 
			
		||||
	Super::GetLifetimeReplicatedProps( OutLifetimeProps );
 | 
			
		||||
 
 | 
			
		||||
@@ -1,61 +1,23 @@
 | 
			
		||||
#include "GasaEffectActor.h"
 | 
			
		||||
 | 
			
		||||
#include "AbilitySystemInterface.h"
 | 
			
		||||
#include "GasaAttributeSet.h"
 | 
			
		||||
#include "GasaAttributeSet_Inlines.h"
 | 
			
		||||
#include "Components/SphereComponent.h"
 | 
			
		||||
 | 
			
		||||
#include "GasaAbilitySystemComponent_Inlines.h"
 | 
			
		||||
using namespace Gasa;
 | 
			
		||||
 | 
			
		||||
AGasaEffectActor::AGasaEffectActor()
 | 
			
		||||
{
 | 
			
		||||
	PrimaryActorTick.bCanEverTick = false;
 | 
			
		||||
 | 
			
		||||
	Mesh   = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
 | 
			
		||||
	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
 | 
			
		||||
 | 
			
		||||
	SetRootComponent(Mesh);
 | 
			
		||||
	Sphere->SetupAttachment(Mesh);
 | 
			
		||||
	RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AGasaEffectActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent
 | 
			
		||||
	, AActor* OtherActor
 | 
			
		||||
	, UPrimitiveComponent* OtherComp
 | 
			
		||||
	, int32 OtherBodyIndex
 | 
			
		||||
	, bool bFromSweep
 | 
			
		||||
	, FHitResult const& SweepResult)
 | 
			
		||||
void AGasaEffectActor::ApplyEffectToTarget(AActor* Target, TSubclassOf<UGameplayEffect> EffectClass)
 | 
			
		||||
{
 | 
			
		||||
	// Demo of "restricted way"
 | 
			
		||||
	if ( ! OtherActor->Implements<UAbilitySystemInterface>())
 | 
			
		||||
		return;
 | 
			
		||||
	UGasaAbilitySystemComp* AS = GetAbilitySystem(Target, true);
 | 
			
		||||
 | 
			
		||||
	FGameplayEffectContextHandle
 | 
			
		||||
	Context = AS->MakeEffectContext();
 | 
			
		||||
	Context.AddSourceObject(Target);
 | 
			
		||||
	
 | 
			
		||||
	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 );
 | 
			
		||||
	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);
 | 
			
		||||
	FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context );
 | 
			
		||||
	AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,39 +1,19 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "GasaCommon.h"
 | 
			
		||||
 | 
			
		||||
#include "GasaEffectActor.generated.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
UCLASS()
 | 
			
		||||
class GASA_API AGasaEffectActor : public AActor
 | 
			
		||||
{
 | 
			
		||||
	GENERATED_BODY()
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	UPROPERTY(VisibleAnywhere)
 | 
			
		||||
	TObjectPtr<UStaticMeshComponent> Mesh;
 | 
			
		||||
	UPROPERTY(VisibleAnywhere)
 | 
			
		||||
	TObjectPtr<USphereComponent> Sphere;
 | 
			
		||||
	UPROPERTY(EditAnywhere, Category = "Applied Effects")
 | 
			
		||||
	TSoftClassPtr<UGameplayEffect> InstantEffectClass;
 | 
			
		||||
	
 | 
			
		||||
	AGasaEffectActor();
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	void ApplyEffectToTarget(AActor* Target, TSubclassOf<UGameplayEffect> EffectClass );
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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 UAttributeSet;
 | 
			
		||||
class UCameraComponent;
 | 
			
		||||
class UGameplayEffect;
 | 
			
		||||
class UInputAction;
 | 
			
		||||
class UInputMappingContext;
 | 
			
		||||
class USphereComponent;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,8 @@ void UHostWidgetController::MaxManaChanged( FOnAttributeChangeData const& Attrib
 | 
			
		||||
 | 
			
		||||
void UHostWidgetController::BroadcastInitialValues()
 | 
			
		||||
{
 | 
			
		||||
	// This function is managed by: GenGasa/GenGasa_HostWidgetController.cpp
 | 
			
		||||
 | 
			
		||||
	UGasaAttributeSet* GasaAttribs = Cast<UGasaAttributeSet>( Data.Attributes );
 | 
			
		||||
	if ( GasaAttribs )
 | 
			
		||||
	{
 | 
			
		||||
@@ -37,10 +39,13 @@ void UHostWidgetController::BroadcastInitialValues()
 | 
			
		||||
		Event_OnManaChanged.Broadcast( GasaAttribs->GetMana() );
 | 
			
		||||
		Event_OnMaxManaChanged.Broadcast( GasaAttribs->GetMaxMana() );
 | 
			
		||||
	}
 | 
			
		||||
	BindCallbacksToDependencies();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UHostWidgetController::BindCallbacksToDependencies()
 | 
			
		||||
{
 | 
			
		||||
	// This function is managed by: GenGasa/GenGasa_HostWidgetController.cpp
 | 
			
		||||
 | 
			
		||||
	UGasaAbilitySystemComp* AbilitySystem = Cast<UGasaAbilitySystemComp>( Data.AbilitySystem );
 | 
			
		||||
	UGasaAttributeSet*      GasaAttribs   = Cast<UGasaAttributeSet>( Data.Attributes );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -301,4 +301,4 @@ void gen_UHostWidgetController()
 | 
			
		||||
		source.write();
 | 
			
		||||
		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 )
 | 
			
		||||
{
 | 
			
		||||
	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,
 | 
			
		||||
		CodeFn field_impl = parse_function( token_fmt(
 | 
			
		||||
			"class_name", class_name, "property", (StrC)property, "from_notice", txt("\n// From GAMEPLAYATTRIBUTE_REPNOTIFY\n"),
 | 
			
		||||
		stringize(
 | 
			
		||||
			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( 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")
 | 
			
		||||
 
 | 
			
		||||
@@ -8635,18 +8635,18 @@ namespace parser
 | 
			
		||||
		result->Type    = Function_Body;
 | 
			
		||||
 | 
			
		||||
		// TODO : Support actual parsing of function body
 | 
			
		||||
		Token start = currtok;
 | 
			
		||||
		Token start = currtok_noskip;
 | 
			
		||||
 | 
			
		||||
		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++;
 | 
			
		||||
 | 
			
		||||
			else if ( currtok.Type == TokType::BraceCurly_Close && level > 0 )
 | 
			
		||||
			else if ( currtok_noskip.Type == TokType::BraceCurly_Close && level > 0 )
 | 
			
		||||
				level--;
 | 
			
		||||
 | 
			
		||||
			eat( currtok.Type );
 | 
			
		||||
			eat( currtok_noskip.Type );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Token previous = prevtok;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user