diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.dll b/Project/Binaries/Win64/UnrealEditor-Gasa.dll index 2279bac..f3801ba 100644 --- a/Project/Binaries/Win64/UnrealEditor-Gasa.dll +++ b/Project/Binaries/Win64/UnrealEditor-Gasa.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d6a6d1ea319e5881451f1d6cab3435b310cb17311cdfecc96379ab4b94c3733 -size 596992 +oid sha256:2230c6cb14601b714954bb70c831b116d14801e27d78748213f2f730644ca305 +size 605696 diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb deleted file mode 100644 index b57607d..0000000 Binary files a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb and /dev/null differ diff --git a/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll b/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll index d0567a9..3d5438c 100644 --- a/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll +++ b/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf0484c765fafd77e419837a7575725e71db7c0fec01443505cb5a24eaa36aa6 +oid sha256:d558410faddece4149f4930726a1b11728cf235a111e8763bac8a43ba10c228d size 79360 diff --git a/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb b/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb deleted file mode 100644 index 0688eaa..0000000 Binary files a/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb and /dev/null differ diff --git a/Project/Config/DefaultEngine.ini b/Project/Config/DefaultEngine.ini index a56d027..ed785c6 100644 --- a/Project/Config/DefaultEngine.ini +++ b/Project/Config/DefaultEngine.ini @@ -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") \ No newline at end of file diff --git a/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent_Inlines.h b/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent_Inlines.h index 10d2f57..907c2f2 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent_Inlines.h +++ b/Project/Source/Gasa/AbilitySystem/GasaAbilitySystemComponent_Inlines.h @@ -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(Actor); + if (ASI) + return Cast(ASI->GetAbilitySystemComponent()); + + if (LookForComponent) + { + // Fall back to a component search to better support BP-only actors + return Cast(Actor->FindComponentByClass()); + } + + return nullptr; + } } diff --git a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp index dbad84b..fae9819 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp +++ b/Project/Source/Gasa/AbilitySystem/GasaAttributeSet.cpp @@ -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( 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( 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( 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( StaticClass(), GET_MEMBER_NAME_CHECKED( UGasaAttributeSet, MaxMana ) ); + GetOwningAbilitySystemComponentChecked()->SetBaseAttributeValueFromReplication( FGameplayAttribute( UGasaAttributeSetProperty ), MaxMana, PrevMaxMana ); } +#pragma endregion Rep Notifies void UGasaAttributeSet::GetLifetimeReplicatedProps( TArray& OutLifetimeProps ) const { Super::GetLifetimeReplicatedProps( OutLifetimeProps ); diff --git a/Project/Source/Gasa/AbilitySystem/GasaEffectActor.cpp b/Project/Source/Gasa/AbilitySystem/GasaEffectActor.cpp index 82b26ee..42367ae 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaEffectActor.cpp +++ b/Project/Source/Gasa/AbilitySystem/GasaEffectActor.cpp @@ -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("Mesh"); - Sphere = CreateDefaultSubobject("Sphere"); - - SetRootComponent(Mesh); - Sphere->SetupAttachment(Mesh); + RootComponent = CreateDefaultSubobject("Root"); } -void AGasaEffectActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent - , AActor* OtherActor - , UPrimitiveComponent* OtherComp - , int32 OtherBodyIndex - , bool bFromSweep - , FHitResult const& SweepResult) +void AGasaEffectActor::ApplyEffectToTarget(AActor* Target, TSubclassOf EffectClass) { - // Demo of "restricted way" - if ( ! OtherActor->Implements()) - return; + UGasaAbilitySystemComp* AS = GetAbilitySystem(Target, true); + + FGameplayEffectContextHandle + Context = AS->MakeEffectContext(); + Context.AddSourceObject(Target); - IAbilitySystemInterface* ASI = Cast(OtherActor); - if (ASI == nullptr) - return; - - // TODO(Ed): Change this to use a gameplay effect instead - UAbilitySystemComponent* AbilitySystem = ASI->GetAbilitySystemComponent(); - UGasaAttributeSet* MutAttributes = const_cast(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 ); } diff --git a/Project/Source/Gasa/AbilitySystem/GasaEffectActor.h b/Project/Source/Gasa/AbilitySystem/GasaEffectActor.h index f315384..f000ac3 100644 --- a/Project/Source/Gasa/AbilitySystem/GasaEffectActor.h +++ b/Project/Source/Gasa/AbilitySystem/GasaEffectActor.h @@ -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 Mesh; - UPROPERTY(VisibleAnywhere) - TObjectPtr Sphere; + UPROPERTY(EditAnywhere, Category = "Applied Effects") + TSoftClassPtr 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 EffectClass ); }; diff --git a/Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.cpp b/Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.cpp new file mode 100644 index 0000000..024e3a2 --- /dev/null +++ b/Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.cpp @@ -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("Mesh"); + Sphere = CreateDefaultSubobject("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()) + return; + + IAbilitySystemInterface* ASI = Cast(OtherActor); + if (ASI == nullptr) + return; + + // TODO(Ed): Change this to use a gameplay effect instead + UAbilitySystemComponent* AbilitySystem = ASI->GetAbilitySystemComponent(); + UGasaAttributeSet* MutAttributes = const_cast(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); +} diff --git a/Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.h b/Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.h new file mode 100644 index 0000000..852468b --- /dev/null +++ b/Project/Source/Gasa/AbilitySystem/GasaEffectActorDemo.h @@ -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 Mesh; + UPROPERTY(VisibleAnywhere) + TObjectPtr 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 +}; diff --git a/Project/Source/Gasa/GasaCommon.h b/Project/Source/Gasa/GasaCommon.h index c847a0b..5870db4 100644 --- a/Project/Source/Gasa/GasaCommon.h +++ b/Project/Source/Gasa/GasaCommon.h @@ -22,6 +22,7 @@ class UAbilitySystemComponent; class UAbilitySystemInterface; class UAttributeSet; class UCameraComponent; +class UGameplayEffect; class UInputAction; class UInputMappingContext; class USphereComponent; diff --git a/Project/Source/Gasa/UI/HostWIdgetController.cpp b/Project/Source/Gasa/UI/HostWIdgetController.cpp index 41f6810..acafe03 100644 --- a/Project/Source/Gasa/UI/HostWIdgetController.cpp +++ b/Project/Source/Gasa/UI/HostWIdgetController.cpp @@ -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( 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( Data.AbilitySystem ); UGasaAttributeSet* GasaAttribs = Cast( Data.Attributes ); diff --git a/Project/Source/GasaGen/GasaGen_HostWidgetController.cpp b/Project/Source/GasaGen/GasaGen_HostWidgetController.cpp index 4187203..b922d59 100644 --- a/Project/Source/GasaGen/GasaGen_HostWidgetController.cpp +++ b/Project/Source/GasaGen/GasaGen_HostWidgetController.cpp @@ -301,4 +301,4 @@ void gen_UHostWidgetController() source.write(); format_file(path_gasa_ui "HostWidgetController.cpp"); } -} \ No newline at end of file +} diff --git a/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp b/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp index e585258..54ff97b 100644 --- a/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp +++ b/Project/Source/GasaGen/GasaGen_UGasaAttributeSet.cpp @@ -307,19 +307,37 @@ void def_attribute_field_initers ( CodeBody body, Array properties 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, + 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) { - GAMEPLAYATTRIBUTE_REPNOTIFY(, , 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") diff --git a/Project/Source/GasaGen/gen.cpp b/Project/Source/GasaGen/gen.cpp index c6299d2..04bdc4b 100644 --- a/Project/Source/GasaGen/gen.cpp +++ b/Project/Source/GasaGen/gen.cpp @@ -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;