Compare commits

...

15 Commits

Author SHA1 Message Date
Ed_
d97ee1d302 Making scripts for major changes 2024-10-18 15:43:22 -04:00
Ed_
1b5d2a3ff6 just origanizing gitignore 2024-10-18 15:15:52 -04:00
Ed_
ca779b627b Commiting last latest changes before making repo modifications 2024-10-18 15:11:13 -04:00
Ed_
a885201b81 60. Animating the Message Widget 2024-04-26 22:04:10 -04:00
Ed_
07c5420bc2 59. Message Widget 2024-04-26 21:36:09 -04:00
Ed_
fe2abe1972 58. Broadcasting Data Table Rows 2024-04-26 20:08:08 -04:00
Ed_
e8fb014d29 54. Get All Asset Tags 2024-04-26 18:23:13 -04:00
Ed_
c4e40037ed 53. Gameplay Effect Delegates 2024-04-25 12:46:26 -04:00
Ed_
33b3723b82 53. Gameplay Effect Delegates 2024-04-25 00:30:54 -04:00
Ed_
ae1e28a072 46. PostGameplayEffectExecute 2024-04-24 20:18:38 -04:00
Ed_
ef002ccf53 45. PreAttributeChange 2024-04-24 18:18:26 -04:00
Ed_
035ad8de6f 44. Infinite Effect Application and Removal 2024-04-24 16:21:22 -04:00
Ed_
a604117e95 43. Instant and Duration Application Policy 2024-04-24 11:58:40 -04:00
Ed_
f17c53a1a9 42. Infinite Gameplay Effects 2024-04-24 11:48:07 -04:00
Ed_
bd0c8a0878 41. Effect Stacking 2024-04-24 11:14:41 -04:00
71 changed files with 888 additions and 320 deletions

51
.gitignore vendored
View File

@ -1,31 +1,38 @@
Project/Binaries
Project/Intermediate
Project/Saved/Crashes
Project/Saved/SourceControl
Project/Saved/ShaderDebugInfo
Project/Saved/Logs
Project/Saved/Autosaves
Project/Saved/Config/CrashReportClient
Project/Saved/Config/WindowsEditor
Project/Saved/Config/WorldState
Project/Saved/AutoScreenshot.png
Project/Platforms
*/Binaries/Win64/*.patch_*.*
Project/.idea
Project/.vs
Project/.vsconfig
*.sln
*.target
*.modules
Project/.idea
Project/Saved/Screenshots
*/Binaries/Win64/*.patch_*.*
Project/Saved/ImGui
Project/Saved/ImGui/imgui.ini
GasaGen_*.pdb
Project/Binaries
Project/Binaries/GasaGen.exe
Project/Binaries/GasaGen.map
Project/Binaries/GasaGen.obj
Project/Binaries/vc140.pdb
Project/Intermediate
Project/Platforms
Project/Saved/Config/ConsoleHistory.ini
*.pdb
Project/Saved/Autosaves
Project/Saved/AutoScreenshot.png
Project/Saved/Config/CrashReportClient
Project/Saved/Config/WindowsEditor
Project/Saved/Config/WorldState
Project/Saved/Crashes
Project/Saved/Diff
Project/Saved/ImGui
Project/Saved/ImGui/imgui.ini
Project/Saved/Logs
Project/Saved/Screenshots
Project/Saved/ShaderDebugInfo
Project/Saved/SourceControl
*.modules
*.pdb
*.sln
*.target
GasaGen_*.pdb

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -49,6 +49,15 @@ r.ReflectionMethod=1
r.Shadow.Virtual.Enable=1
r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True
r.CustomDepth=3
r.DefaultFeature.Bloom=False
r.DefaultFeature.AmbientOcclusion=False
r.DefaultFeature.AmbientOcclusionStaticFraction=False
r.DefaultFeature.AutoExposure=False
r.DefaultFeature.MotionBlur=False
r.AntiAliasingMethod=0
r.MSAACount=1
r.ScreenPercentage.Default=25.000000
r.SupportSkyAtmosphere=False
[/Script/WorldPartitionEditor.WorldPartitionEditorSettings]
CommandletClass=Class'/Script/UnrealEd.WorldPartitionConvertCommandlet'
@ -130,3 +139,4 @@ ManualIPAddress=
+CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
+CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
+CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")

View File

@ -10,6 +10,7 @@ Tag_GlobalPPV=Global_PPV
Template_PlayerCamera=/Game/Actors/BP_CameraMount.BP_CameraMount_C
Template_HUD_HostUI=/Game/UI/UI_Host.UI_Host_C
Template_HostWidgetController=/Game/UI/BP_HostWidgetController.BP_HostWidgetController_C
TaggedMessageTable=/Game/Core/Tables/DT_TaggedMessages.DT_TaggedMessages
[/Script/GameplayAbilities.AbilitySystemGlobals]
bUseDebugTargetFromHud=true

View File

@ -0,0 +1,20 @@
[/Script/GameplayTags.GameplayTagsSettings]
ImportTagsFromConfig=True
WarnOnInvalidTags=True
ClearInvalidTags=False
AllowEditorTagUnloading=True
AllowGameTagUnloading=False
FastReplication=False
InvalidTagCharacters="\"\',"
+GameplayTagTableList=/Game/Core/Tables/DT_PrimaryAttributes.DT_PrimaryAttributes
NumBitsForContainerSize=6
NetIndexFirstBitSegment=16
+GameplayTagList=(Tag="Attributes.Vital.Health",DevComment="")
+GameplayTagList=(Tag="Attributes.Vital.Mana",DevComment="")
+GameplayTagList=(Tag="Attributes.Vital.MaxHealth",DevComment="")
+GameplayTagList=(Tag="Attributes.Vital.MaxMana",DevComment="")
+GameplayTagList=(Tag="Message.Crystal.Health",DevComment="")
+GameplayTagList=(Tag="Message.Crystal.Mana",DevComment="")
+GameplayTagList=(Tag="Message.Potion.Health",DevComment="")
+GameplayTagList=(Tag="Message.Potion.Mana",DevComment="")

BIN
Project/Content/Core/AbilitySystem/GE_AreaFire.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Project/Content/Core/BP_AreaFire_RawEffect.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/Core/DT_PrimaryAttributes.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/Core/DT_TaggedMessages.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/Core/Game/BP_HUD.uasset (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Project/Content/Core/Pickups/BP_ManaCrystal_RawEffect.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
Project/Content/Core/Tables/CT_Potion.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/Core/Tables/DT_PrimaryAttributes.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/Core/Tables/DT_TaggedMessages.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/Levels/StartupMap.umap (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Project/Content/UI/DT_StyleText_EffectMessage.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/UI/Globes/MI_BlackBG.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/UI/RTD_Default.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/UI/UI_EffectMessage.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Project/Content/UI/UI_GlobeTemplate.uasset (Stored with Git LFS)

Binary file not shown.

BIN
Project/Content/UI/UI_Host.uasset (Stored with Git LFS)

Binary file not shown.

View File

@ -0,0 +1,7 @@
{
"ColumnWidths":
{
"DevComment": 405,
"Tag": 381
}
}

View File

@ -0,0 +1,6 @@
{
"ColumnWidths":
{
"TextStyle": 1099
}
}

View File

@ -0,0 +1,9 @@
{
"ColumnWidths":
{
"Image": 487,
"Tag": 246,
"Message": 439,
"MessageTemplate": 232
}
}

View File

@ -0,0 +1,38 @@
#include "EffectProperties.h"
#include "AbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#include "GameplayEffect.h"
#include "GameplayEffectExtension.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/PlayerController.h"
void FEffectProperties::Populate(FGameplayEffectModCallbackData const& Data)
{
Context = Data.EffectSpec.GetContext();
SourceAbilitySystem = Context.GetOriginalInstigatorAbilitySystemComponent();
if (IsValid(SourceAbilitySystem)
&& SourceAbilitySystem->AbilityActorInfo.IsValid()
&& SourceAbilitySystem->AbilityActorInfo->AvatarActor.IsValid())
{
FGameplayAbilityActorInfo* AbilityInfo = SourceAbilitySystem->AbilityActorInfo.Get();
SourceAvatar = AbilityInfo->AvatarActor.Get();
SourceController = AbilityInfo->PlayerController.Get();
if (SourceController == nullptr && SourceAvatar)
{
APawn* Pawn = Cast<APawn>(SourceAvatar);
if (Pawn)
SourceController = Pawn->GetController();
}
}
if (Data.Target.AbilityActorInfo.IsValid() && Data.Target.AbilityActorInfo->AvatarActor.IsValid())
{
FGameplayAbilityActorInfo* AbilityInfo = Data.Target.AbilityActorInfo.Get();
TargetAvatar = AbilityInfo->AvatarActor.Get();
TargetController = AbilityInfo->PlayerController.Get();
TargetAbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(TargetAvatar);
}
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "GameplayEffectTypes.h"
#include "GasaCommon.h"
#include "EffectProperties.generated.h"
USTRUCT()
struct GASA_API FEffectProperties
{
GENERATED_BODY()
FGameplayEffectContextHandle Context;
UPROPERTY(VisibleAnywhere)
UAbilitySystemComponent* SourceAbilitySystem;
UPROPERTY(VisibleAnywhere)
AActor* SourceAvatar;
UPROPERTY(VisibleAnywhere)
AController* SourceController;
UPROPERTY(VisibleAnywhere)
UAbilitySystemComponent* TargetAbilitySystem;
UPROPERTY(VisibleAnywhere)
AActor* TargetAvatar;
UPROPERTY(VisibleAnywhere)
APlayerController* TargetController;
void Populate(FGameplayEffectModCallbackData const& Data);
};

View File

@ -1 +1,33 @@
#include "GasaAbilitySystemComponent.h"
#include "Engine/Engine.h"
#include "Engine/GameViewportClient.h"
#include "Game/GasaGameState.h"
#include "Game/GasaPlayerController.h"
#include "GameFramework/HUD.h"
#include "Slate/SceneViewport.h"
#include "UI/GasaHUD.h"
#include "CogDebugDraw.h"
using namespace Gasa;
void UGasaAbilitySystemComp::OnAbilityActorInfoSet()
{
if ( ! OnGameplayEffectAppliedDelegateToSelf.IsBoundToObject(this))
OnGameplayEffectAppliedDelegateToSelf.AddUObject(this, & ThisClass::EffectApplied);
}
void UGasaAbilitySystemComp::EffectApplied(UAbilitySystemComponent* AbilitySystem, FGameplayEffectSpec const& Spec,
FActiveGameplayEffectHandle ActiveEffect)
{
Log("EFFECT APPLIED?");
FGameplayTagContainer Tags;
Spec.GetAllAssetTags(Tags);
Event_OnEffectAppliedAssetTags.Broadcast(Tags);
}
void UGasaAbilitySystemComp::InitAbilityActorInfo(AActor* InOwnerActor, AActor* InAvatarActor)
{
Super::InitAbilityActorInfo(InOwnerActor, InAvatarActor);
}

View File

@ -1,15 +1,27 @@
#pragma once
#include "AbilitySystemComponent.h"
#include "GasaCommon.h"
#include "GasaAbilitySystemComponent.generated.h"
DECLARE_MULTICAST_DELEGATE_OneParam(FEffectAssetTagsSig, FGameplayTagContainer const& /*Tags*/);
UCLASS(BlueprintType)
class GASA_API UGasaAbilitySystemComp : public UAbilitySystemComponent
{
GENERATED_BODY()
public:
FEffectAssetTagsSig Event_OnEffectAppliedAssetTags;
void OnAbilityActorInfoSet();
void EffectApplied(UAbilitySystemComponent* AbilitySystem, FGameplayEffectSpec const& Spec, FActiveGameplayEffectHandle ActiveEffect);
#pragma region AbilitySystemComponent
void InitAbilityActorInfo(AActor* InOwnerActor, AActor* InAvatarActor) override;
#pragma endregion AbilitySystemComponent
};

View File

@ -18,7 +18,7 @@ namespace Gasa
// From: UAbilitySystemGlobals::GetAbilitySystemComponentFromActor
inline
UGasaAbilitySystemComp* GetAbilitySystem(AActor* Actor, bool LookForComponent = false)
UGasaAbilitySystemComp* GetAbilitySystem(AActor* Actor, bool LookForComponent = true)
{
if (Actor == nullptr)
return nullptr;

View File

@ -1,6 +1,7 @@
// Generated by GasaGen/GasaGen_UGasaAttributeSet.cpp
#include "GasaAttributeSet.h"
#include "GasaAttributeSet_Inlines.h"
#include "EffectProperties.h"
#include "AbilitySystemComponent.h"
#include "Net/UnrealNetwork.h"
@ -8,9 +9,9 @@
UGasaAttributeSet::UGasaAttributeSet()
{
InitHealth( 50.f );
InitHealth( 100.f );
InitMaxHealth( 100.f );
InitMana( 25.f );
InitMana( 50.f );
InitMaxMana( 50.f );
}
@ -41,6 +42,35 @@ void UGasaAttributeSet::Client_OnRep_MaxMana( FGameplayAttributeData& PrevMaxMan
}
#pragma endregion Rep Notifies
void UGasaAttributeSet::PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data )
{
Super::PostGameplayEffectExecute( Data );
FEffectProperties Props;
Props.Populate( Data );
}
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
{
Super::GetLifetimeReplicatedProps( OutLifetimeProps );

View File

@ -9,20 +9,16 @@ class GASA_API UGasaAttributeSet : public UAttributeSet
{
GENERATED_BODY()
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();
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()
void Client_OnRep_Health( FGameplayAttributeData& PrevHealth );
@ -90,6 +86,12 @@ public:
}
#pragma endregion Setters
#pragma region AttributeSet
void
PreAttributeChange( const FGameplayAttribute& Attribute, float& NewValue ) override;
void PostGameplayEffectExecute( FGameplayEffectModCallbackData const& Data ) override;
#pragma endregion AttributeSet
#pragma region UObject
void
GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override;

View File

@ -1,6 +1,7 @@
#include "GasaEffectActor.h"
#include "GasaAbilitySystemComponent_Inlines.h"
#include "GasaContainers.h"
using namespace Gasa;
AGasaEffectActor::AGasaEffectActor()
@ -8,16 +9,118 @@ AGasaEffectActor::AGasaEffectActor()
PrimaryActorTick.bCanEverTick = false;
RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
Level = 1.f;
InstantEffectUsage = EInstantEffectUsagePolicy::DoNotApply;
DurationEffectUsage = DefaultEffectUsagePolicy;
InfiniteEffectUsage = DefaultEffectUsagePolicy;
bDestroyOnEffectRemoval = false;
}
void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass)
void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap)
{
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
FGameplayEffectContextHandle
Context = AS->MakeEffectContext();
Context.AddSourceObject(Actor);
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context );
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (bRemoveOnEndOverlap)
ActiveEffectsToRemove.Add(ActiveEffect, AS);
}
void AGasaEffectActor::OnOverlap(AActor* Actor)
{
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
FGameplayEffectContextHandle
Context = AS->MakeEffectContext();
Context.AddSourceObject(Actor);
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap)
{
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
}
if (DurationEffectClass)
{
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap))
{
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
ActiveDuration = ActiveEffect;
}
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
AS->RemoveActiveGameplayEffect(ActiveDuration);
}
if (InfiniteEffectClass)
{
bool bApplyOnOverlap = Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnOverlap);
if (bApplyOnOverlap)
{
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
ActiveInfinite = ActiveEffect;
}
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
{
if (ActiveInfinite.IsValid())
AS->RemoveActiveGameplayEffect(ActiveInfinite);
}
}
}
void AGasaEffectActor::OnEndOverlap(AActor* Actor)
{
UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true);
FGameplayEffectContextHandle
Context = AS->MakeEffectContext();
Context.AddSourceObject(Actor);
if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnEndOverlap)
{
FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, Level, Context );
AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
}
if (DurationEffectClass)
{
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
{
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( DurationEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
ActiveDuration = ActiveEffect;
}
if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
AS->RemoveActiveGameplayEffect(ActiveDuration);
}
if (InfiniteEffectClass)
{
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap))
{
FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InfiniteEffectClass, Level, Context );
FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );
if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap))
ActiveInfinite = ActiveEffect;
}
if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap))
{
if (ActiveInfinite.IsValid())
AS->RemoveActiveGameplayEffect(ActiveInfinite);
}
}
TArray<FActiveGameplayEffectHandle> EffectsRemoved;
for (ActiveEffectEntry ActiveEffect : ActiveEffectsToRemove)
{
if (ActiveEffect.Value != AS)
continue;
AS->RemoveActiveGameplayEffect(ActiveEffect.Key, 1);
EffectsRemoved.Add(ActiveEffect.Key);
}
RemoveKeys(ActiveEffectsToRemove, EffectsRemoved);
}

View File

@ -2,25 +2,77 @@
#include "GasaCommon.h"
#include "Actors/GasaActor.h"
#include "ActiveGameplayEffectHandle.h"
#include "GameFramework/Actor.h"
#include "GasaEffectActor.generated.h"
struct FActiveGameplayEffectHandle;
UENUM(BlueprintType)
enum class EInstantEffectUsagePolicy : uint8
{
DoNotApply,
ApplyOnOverlap,
ApplyOnEndOverlap,
};
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class EEffectUsagePolicy : uint8
{
None = 0 UMETA(Hidden),
ApplyOnOverlap = bit(0),
ApplyOnEndOverlap = bit(1),
RemoveOnOverlap = bit(2),
RemoveOnEndOverlap = bit(3),
};
constexpr int32 DefaultEffectUsagePolicy = (int32(EEffectUsagePolicy::RemoveOnEndOverlap));
UCLASS()
class GASA_API AGasaEffectActor : public AGasaActor
{
GENERATED_BODY()
public:
AGasaEffectActor();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
float Level;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
TSubclassOf<UGameplayEffect> InstantEffectClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
EInstantEffectUsagePolicy InstantEffectUsage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
TSubclassOf<UGameplayEffect> DurationEffectClass;
AGasaEffectActor();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy"))
int32 DurationEffectUsage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
TSubclassOf<UGameplayEffect> InfiniteEffectClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy"))
int32 InfiniteEffectUsage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects")
bool bDestroyOnEffectRemoval;
TMap<FActiveGameplayEffectHandle, UAbilitySystemComponent*> ActiveEffectsToRemove;
using ActiveEffectEntry = TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*>;
FActiveGameplayEffectHandle ActiveDuration;
FActiveGameplayEffectHandle ActiveInfinite;
UFUNCTION(BlueprintCallable, Category = "Gameplay Effects")
void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass );
};
void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap = false);
UFUNCTION(BlueprintCallable)
void OnOverlap(AActor* Actor);
UFUNCTION(BlueprintCallable)
void OnEndOverlap(AActor* Actor);
};

View File

@ -156,11 +156,12 @@ void AGasaCharacter::PossessedBy(AController* NewController)
GetMesh()->bOnlyAllowAutonomousTickPose = true;
}
#if 0
if (bAutoAbilitySystem)
{
// TODO(Ed): Do we need to do this for enemies?
AbilitySystem->InitAbilityActorInfo(this, this);
}
#endif
}
void AGasaCharacter::SetPlayerDefaults()
@ -179,10 +180,12 @@ void AGasaCharacter::BeginPlay()
{
Super::BeginPlay();
// TODO(Ed): Find out if this is the best spot todo this
// There is also OnPossessed, PostInitializeComponents, etc...
if (bAutoAbilitySystem)
{
// TODO(Ed): Do we need to do this for enemies?
AbilitySystem->InitAbilityActorInfo(this, this);
Cast<UGasaAbilitySystemComp>(AbilitySystem)->OnAbilityActorInfoSet();
}
}

View File

@ -45,7 +45,7 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework")
EGameFrameworkState GameFrameworkState;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework", meta=(Bitmask, BitmaskEnum = EGameFrameworkClassFlag))
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EGameFrameworkClassFlag"))
int32 GameFrameworkClassesState;
UFUNCTION(BlueprintCallable, Category="GameFramework")

View File

@ -232,8 +232,7 @@ void AGasaGameMode::HandleSeamlessTravelPlayer(AController*& Controller)
void AGasaGameMode::InitializeHUDForPlayer_Implementation(APlayerController* NewPlayer)
{
// Super::InitializeHUDForPlayer_Implementation(NewPlayer);
NewPlayer->ClientSetHUD(HUDClass);
Super::InitializeHUDForPlayer_Implementation(NewPlayer);
}
void AGasaGameMode::InitSeamlessTravelPlayer(AController* NewController)

View File

@ -1,147 +0,0 @@
#include "GasaGameState.h"
#include "CogAll.h"
#include "CogWindowManager.h"
#include "GasaPlayerState.h"
#include "GasaGameInstance.h"
#include "Net/UnrealNetwork.h"
#include "Networking/GasaNetLibrary_Inlines.h"
using namespace Gasa;
AGasaGameState::AGasaGameState()
{
// Enable ticking
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.SetTickFunctionEnable(true);
PrimaryActorTick.bStartWithTickEnabled = true;
// Replication
bReplicates = true;
bNetLoadOnClient = false;
NetDormancy = DORM_Awake;
NetCullDistanceSquared = NetCullDist_Default;
NetUpdateFrequency = 10.0f;
MinNetUpdateFrequency = 1.0f;
NetPriority = 5.0f;
}
#pragma region GameFramework
void AGasaGameState::OnGameFrameworkInitialized()
{
NetLog("Received gameplay framework initialization.");
if (IsServer())
{
if (PlayerArray.Num() > 0)
{
ListenServerHost = Cast<AGasaPlayerState>(PlayerArray[0]);
}
else
{
NetLog("Was not able to assign HostingPlayer!", ELogV::Error);
}
}
BP_OnGameFrameworkInitialized();
}
#pragma endregion GameFramework
#pragma region Networking
void AGasaGameState::Client_OnRep_OnlinePlayers()
{
}
#pragma endregion Networking
#pragma region Seamless Travel
void AGasaGameState::Multicast_R_NotifySeamlessTravelEnd_Implementation()
{
NetLog("Multicast_R_NotifySeamlessTravelEnd_Implementation");
BP_Event_OnSeamlessTravelEnd.Broadcast();
Event_OnSeamlessTravelEnd.Broadcast();
}
#pragma endregion Seamless Travel
#pragma region GameStateBase
void AGasaGameState::HandleBeginPlay()
{
Super::HandleBeginPlay();
NetLog("HandleBeginPlay: Directly called from GM");
}
void AGasaGameState::SeamlessTravelTransitionCheckpoint(bool bToTransitionMap)
{
Super::SeamlessTravelTransitionCheckpoint(bToTransitionMap);
NetLog("SeamlessTravelTransitionCheckpoint");
NetLog(FString("ToTransitionMap: ") + FString(bToTransitionMap ? "true" : "false"));
if (bToTransitionMap)
{
Event_OnSeamlessTravelStart.Broadcast();
}
else
{
Multicast_R_NotifySeamlessTravelEnd();
}
}
#pragma endregion GameStateBase
#pragma region Actor
void AGasaGameState::BeginPlay()
{
Super::BeginPlay();
NetLog("BeginPlay");
// Notified as initialized here as any possible components should also be initialized by this point.
UGasaGameInstance*
GI = GetGameInstance<UGasaGameInstance>();
GI->Event_OnGameFrameworkInitialized.AddDynamic(this, & ThisClass::OnGameFrameworkInitialized);
GI->NotifyGameFrameworkClassReady(EGameFrameworkClassFlag::GameState);
#if ENABLE_COG
CogWindowManager = NewObject<UCogWindowManager>(this);
CogWindowManagerRef = CogWindowManager;
// Add all the built-in windows
Cog::AddAllWindows(*CogWindowManager);
#endif //ENABLE_COG
}
void AGasaGameState::PostInitializeComponents()
{
NetLog("PostInitializeComponents");
Super::PostInitializeComponents();
if ( ! GetWorld()->IsEditorWorld() && IsServer())
{
OnlinePlayers.Empty();
#if 0
const auto GI = Cast<UGasaGameInstance>(GetGameInstance());
if (GI != nullptr)
{
int32 NumConnections = GI->SessionSettings.bPublicGame
? GI->SessionSettings.PublicConnections
: GI->SessionSettings.PrivateConnections;
OnlinePlayers.Init(nullptr, NumConnections);
}
#endif
}
}
void AGasaGameState::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
#if ENABLE_COG
if (CogWindowManager)
CogWindowManager->Tick(DeltaSeconds);
#endif //ENABLE_COG
}
#pragma endregion Actor
#pragma region UObject
void AGasaGameState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AGasaGameState, ListenServerHost);
DOREPLIFETIME(AGasaGameState, OnlinePlayers);
}
#pragma endregion UObject

View File

@ -3,6 +3,7 @@
#include "Networking/GasaNetLibrary_Inlines.h"
#include "AbilitySystemComponent.h"
#include "DrawDebugHelpers.h"
#include "Engine/LocalPlayer.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
@ -18,6 +19,7 @@
#include "GasaGameInstance.h"
#include "GasaGameState.h"
#include "GasaPlayerState.h"
#include "AbilitySystem/GasaAbilitySystemComponent.h"
#include "Actors/CameraMount.h"
#include "UI/GasaHUD.h"
#include "UI/WidgetController.h"
@ -66,14 +68,18 @@ void AGasaPlayerController::NetOwner_OnReady()
if (IsClient())
ServerRPC_R_NotifyOwningClientReady();
Cam = GetWorld()->SpawnActor<ACameraMount>(GetDevOptions()->Template_PlayerCamera.Get(), FActorSpawnParameters() );
SetViewTarget(Cam);
AGasaPlayerState* PS = GetPlayerState();
APlayerCharacter* PlayerChar = GetPawn<APlayerCharacter>();
{
PlayerChar->AbilitySystem = PS->AbilitySystem;
PlayerChar->Attributes = PS->Attributes;
PlayerChar->AbilitySystem->InitAbilityActorInfo(PS, this);
Cam->AttachToActor(PlayerChar, FAttachmentTransformRules::KeepRelativeTransform);
PS->AbilitySystem->InitAbilityActorInfo(PS, PlayerChar);
Cast<UGasaAbilitySystemComp>(PS->AbilitySystem)->OnAbilityActorInfoSet();
}
Cam->AttachToActor(PlayerChar, FAttachmentTransformRules::KeepRelativeTransform);
}
void AGasaPlayerController::OnGameFrameworkInitialized()
@ -416,15 +422,11 @@ void AGasaPlayerController::BeginPlay()
void AGasaPlayerController::PostInitializeComponents()
{
Super::PostInitializeComponents();
Cam = GetWorld()->SpawnActor<ACameraMount>(GetDevOptions()->Template_PlayerCamera.Get(), FActorSpawnParameters() );
SetViewTarget(Cam);
}
void AGasaPlayerController::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
#if 0
switch (HighlightState)
{

View File

@ -84,6 +84,15 @@ public class Gasa : ModuleRules
PrivateIncludePathModuleNames.AddRange( new string[]
{
"CogCommon",
"CogAbility",
"CogAI",
"CogAll",
"CogDebug",
"CogDebugEditor",
"CogEngine",
"CogImgui",
"CogInput",
"CogWindow",
});
PrivateDependencyModuleNames.AddRange(new string[]
{

View File

@ -13,12 +13,17 @@
#define rcast( Type, Value ) reinterpret_cast<Type>( Value )
#define scast( Type, Value ) static_cast<Type>( Value )
#define bit(position) (1 << position)
#pragma region Math
#define m_pow2( value ) (value * value)
#pragma endregion Math
#pragma region Engine Forwards
struct FInputActionValue;
struct FGameplayEffectContextHandle;
struct FGameplayEffectModCallbackData;
struct FGameplayTagContainer;
struct FOnAttributeChangeData;
struct FReplicationFlags;
@ -40,6 +45,7 @@ class UInputAction;
class UInputMappingContext;
class USphereComponent;
class USpringArmComponent;
class UTexture2D;
#pragma endregion Engine Forwards
#pragma region Engine Plugin Forwards
@ -68,6 +74,7 @@ class UGasaObject;
class UGasaOverlay;
class UGasaProgressBar;
class UGasaSizeBox;
class UGasaUserWidget;
class UHostWidgetController;
class UHUDHostWidget;
class UWidgetController;
@ -78,13 +85,30 @@ namespace Gasa
{
inline
bool Bitfield_IsSet(int32 Bitfield, int32 Bitmask) {
int32 Result = Bitmask == (Bitfield & Bitmask);
return scast(bool, Result);
bool Result = Bitmask == (Bitfield & Bitmask);
return Result;
}
inline
bool Bitfield_IsSetExactly(int32 Bitfield, int32 Bitmask)
{
bool Result = Bitfield == (Bitfield & Bitmask);
return Result;
}
inline void Bitfield_Set ( int32& Bitfield, int32 BitsToAdd ) { Bitfield |= BitsToAdd; }
inline void Bitfield_Remove( int32& Bitfield, int32 BitsToRemove ) { Bitfield &= (! BitsToRemove); }
inline void Bitfield_Toggle( int32& Bitfield, int32 Bitmask ) { Bitfield ^= Bitmask; }
template<typename EnumType>
inline
bool Bitfield_IsSet(int32 Bitfield, EnumType Mask)
{
bool Result = int32(Mask) == (Bitfield & int32(Mask));
return Result;
}
template<typename EnumType> inline void Bitfield_Set ( int32& Bitfield, EnumType BitToAdd ) { Bitfield |= int32(BitToAdd); }
template<typename EnumType> inline void Bitfield_Remove( int32& Bitfield, EnumType BitToRemove ) { Bitfield &= (! int32(BitToRemove)); }
template<typename EnumType> inline void Bitfield_Toggle( int32& Bitfield, EnumType BitToToggle ) { Bitfield ^= int32(BitToToggle); }
}
#pragma endregion Bitfields
@ -139,7 +163,8 @@ namespace Gasa
// Works for Unreal 5.4, Win64 MSVC (untested in other scenarios, for now)
inline
void Log( FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log
void Log( FString Message
, EGasaVerbosity Verbosity = EGasaVerbosity::Log
, FLogCategoryBase& Category = LogGasa
, bool DumpStack = false
, int32 Line = __builtin_LINE()

View File

View File

@ -0,0 +1,22 @@
#pragma once
#include "GasaCommon.h"
template<typename RowType>
inline
RowType* GetDataTableRowByTag(UDataTable* DT, FGameplayTag& Tag)
{
RowType* Row = DT->FindRow<RowType>(Tag.GetTagName(), TEXT(""));
return Row;
}
template<typename KeyType, typename ValueType>
inline
void RemoveKeys(TMap<KeyType, ValueType> Map, TArray<KeyType> Keys)
{
for (KeyType& Key : Keys )
{
Map.Remove(Key);
}
}

View File

@ -1,11 +1,12 @@
#pragma once
#include "Engine/DataTable.h"
#include "Engine/DeveloperSettings.h"
#include "GasaCommon.h"
#include "GasaDevOptions.generated.h"
UCLASS(Config=Game, DefaultConfig, meta=(DisplayName="Gasa"))
class GASA_API UGasaDevOptions : public UDeveloperSettings
{
@ -15,6 +16,9 @@ public:
// NOTE(Ed): Any Soft-References must have their includes defined in GasaDevOptions.cpp
// They are used by GasaGen for the GasaDevOptionsCache
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
TSoftObjectPtr<UDataTable> TaggedMessageTable;
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="UI")
TSoftClassPtr<ACameraMount> Template_PlayerCamera;

View File

@ -11,6 +11,9 @@ void FGasaDevOptionsCache::CachedDevOptions()
{
UGasaDevOptions* DevOpts = GetMutDevOptions();
TaggedMessageTable = DevOpts->TaggedMessageTable.LoadSynchronous();
ensureMsgf( TaggedMessageTable != nullptr, TEXT( "TaggedMessageTable is null, DO NOT RUN PIE or else you may get a crash if not handled in BP or C++" ) );
Template_PlayerCamera = DevOpts->Template_PlayerCamera.LoadSynchronous();
ensureMsgf(
Template_PlayerCamera != nullptr, TEXT( "Template_PlayerCamera is null, DO NOT RUN PIE or else you may get a crash if not handled in BP or C++" )

View File

@ -8,6 +8,8 @@ struct GASA_API FGasaDevOptionsCache
{
GENERATED_BODY()
UPROPERTY()
UObject* TaggedMessageTable;
UPROPERTY()
UClass* Template_PlayerCamera;
UPROPERTY()

View File

@ -14,12 +14,15 @@ void AGasaHUD::InitHostWidget(FWidgetControllerData const* WidgetControllerData)
HostWidgetController = NewObject<UHostWidgetController>(this, GetDevOptions()->Template_HostWidgetController.Get());
HostWidgetController->Data = (* WidgetControllerData);
HostWidget->SetWidgetController(HostWidgetController);
HostWidgetController->BindCallbacksToDependencies();
HostWidgetController->BroadcastInitialValues();
HostWidget->AddToViewport();
}
void AGasaHUD::DrawHUD()
{
Super::DrawHUD();
}
#pragma region HUD
void AGasaHUD::ShowHUD()
{
@ -32,4 +35,9 @@ void AGasaHUD::BeginPlay()
{
Super::BeginPlay();
}
void AGasaHUD::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
}
#pragma endregion Actor

View File

@ -22,10 +22,13 @@ public:
void InitHostWidget(FWidgetControllerData const* WidgetControllerData);
#pragma region HUD
void DrawHUD() override;
void ShowHUD() override;
#pragma endregion HUD
#pragma region Actor
void BeginPlay() override;
void Tick(float DeltaSeconds) override;
#pragma endregion Actor
};

View File

@ -1,4 +1,4 @@
#include "GasaUserWidget.h"
#include "GasaUserWidget.h"
#include "Blueprint/WidgetBlueprintGeneratedClass.h"
#include "Blueprint/WidgetTree.h"
@ -227,7 +227,7 @@ bool UGasaUserWidget::Initialize()
// For backward compatibility, run the initialize event on widget that doesn't have a player context only when the class authorized it.
bool bClassWantsToRunInitialized = BGClass && BGClass->bCanCallInitializedWithoutPlayerContext;
if (!IsDesignTime() && (PlayerContext.IsValid() || bClassWantsToRunInitialized))
if (!IsDesignTime() && (GetPlayerContext().IsValid() || bClassWantsToRunInitialized))
{
NativeOnInitialized();
}

View File

@ -1,4 +1,4 @@
#include "GlobeProgressBar.h"
#include "GlobeProgressBar.h"
#include "GasaImage.h"
#include "GasaOverlay.h"

View File

@ -2,6 +2,9 @@
#include "AbilitySystem/GasaAbilitySystemComponent_Inlines.h"
#include "AbilitySystem/GasaAttributeSet.h"
#include "GameplayEffectTypes.h"
#include "GasaDevOptions.h"
#include "TaggedMessageRow.h"
using namespace Gasa;
@ -30,6 +33,20 @@ void UHostWidgetController::MaxManaChanged( FOnAttributeChangeData const& Attrib
}
#pragma endregion Attribute Changed Callbacks
void UHostWidgetController::OnEffectAppliedAssetTags( FGameplayTagContainer const& AssetTags )
{
UDataTable* TaggedMessages = GetDevOptions()->TaggedMessageTable.Get();
for ( FGameplayTag const& Tag : AssetTags )
{
FGameplayTag MessageTagCategory = FGameplayTag::RequestGameplayTag( FName( "Message" ) );
if ( ! Tag.MatchesTag( MessageTagCategory ) )
continue;
FTaggedMessageRow* Row = TaggedMessages->FindRow<FTaggedMessageRow>( Tag.GetTagName(), TEXT( "" ) );
OnTaggedAssetMessage.Broadcast( *Row );
}
}
void UHostWidgetController::BroadcastInitialValues()
{
// This function is managed by: GenGasa/GenGasa_HostWidgetController.cpp
@ -66,4 +83,6 @@ void UHostWidgetController::BindCallbacksToDependencies()
FOnGameplayAttributeValueChange& MaxManaAttributeChangedDelegate =
AbilitySystem->GetGameplayAttributeValueChangeDelegate( GasaAttribs->GetMaxManaAttribute() );
MaxManaAttributeChangedDelegate.AddUObject( this, &ThisClass::MaxManaChanged );
AbilitySystem->Event_OnEffectAppliedAssetTags.AddUObject( this, &UHostWidgetController::OnEffectAppliedAssetTags );
}

View File

@ -1,8 +1,11 @@
#pragma once
#include "GasaCommon.h"
#include "TaggedMessageRow.h"
#include "WidgetController.h"
#include "HostWidgetController.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FAttributeFloatChangedSig, float, NewValue );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FAttributeChangedSig, float, NewValue );
UCLASS( Blueprintable, BlueprintType )
class GASA_API UHostWidgetController : public UWidgetController
@ -13,16 +16,16 @@ public:
// Attribute Events are generated by GasaGen/GasaGen_HostWidgetController.cpp
UPROPERTY( BlueprintAssignable, Category = "Attributes" )
FAttributeFloatChangedSig Event_OnHealthChanged;
FAttributeChangedSig Event_OnHealthChanged;
UPROPERTY( BlueprintAssignable, Category = "Attributes" )
FAttributeFloatChangedSig Event_OnMaxHealthChanged;
FAttributeChangedSig Event_OnMaxHealthChanged;
UPROPERTY( BlueprintAssignable, Category = "Attributes" )
FAttributeFloatChangedSig Event_OnManaChanged;
FAttributeChangedSig Event_OnManaChanged;
UPROPERTY( BlueprintAssignable, Category = "Attributes" )
FAttributeFloatChangedSig Event_OnMaxManaChanged;
FAttributeChangedSig Event_OnMaxManaChanged;
void HealthChanged( FOnAttributeChangeData const& Data );
void MaxHealthChanged( FOnAttributeChangeData const& Data );
@ -30,6 +33,11 @@ public:
void MaxManaChanged( FOnAttributeChangeData const& Data );
#pragma endregion Attribute Events
UPROPERTY( BlueprintAssignable, Category = "Messages" )
FTaggedMessageRowSig OnTaggedAssetMessage;
void OnEffectAppliedAssetTags( FGameplayTagContainer const& AssetTags );
#pragma region WidgetController
void BroadcastInitialValues() override;
void BindCallbacksToDependencies() override;

View File

@ -0,0 +1,28 @@
#pragma once
#include "GameplayTagContainer.h"
#include "GasaCommon.h"
#include "Engine/DataTable.h"
#include "Templates/SubclassOf.h"
#include "TaggedMessageRow.generated.h"
USTRUCT(BlueprintType)
struct FTaggedMessageRow : public FTableRowBase
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FGameplayTag Tag;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FText Message;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TSubclassOf<UGasaUserWidget> MessageTemplate;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UTexture2D* Image;
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTaggedMessageRowSig, FTaggedMessageRow, Message);

View File

@ -77,6 +77,9 @@ CodeBody parse_file( char const* path ) {
return code;
}
// inline
// CodeConstructor find_constructor( StrC parent_name, )
inline
void format_file( char const* path )
{

View File

@ -4,11 +4,12 @@
#include "gen.hpp"
#include "gen.builder.hpp"
#include "GasaGenCommon.cpp"
#include "GasaGen_UGasaAttributeSet.cpp"
#endif
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");
{
@ -64,21 +65,21 @@ void gen_UHostWidgetController()
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(
UPROPERTY(BlueprintAssignable, Category = "Attributes")
));
attribute_events.append(fmt_newline);
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( FAttributeChangedSig Event_On<field>Changed; ))
));
attribute_events.append(fmt_newline);
}
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(
token_fmt( "field", (StrC) attribute_field, stringize( void <field>Changed(FOnAttributeChangeData const& Data); ))
@ -154,9 +155,9 @@ void gen_UHostWidgetController()
CodeFn BroadcastInitialValues = NoCode;
{
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>() ); )
));
}
@ -185,9 +186,9 @@ void gen_UHostWidgetController()
CodeBody bindings = def_body(ECode::Function_Body);
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(
FOnGameplayAttributeValueChange& <field>AttributeChangedDelegate = AbilitySystem->GetGameplayAttributeValueChangeDelegate(GasaAttribs->Get<field>Attribute());
<field>AttributeChangedDelegate.AddUObject(this, &ThisClass::<field>Changed);
@ -208,6 +209,8 @@ void gen_UHostWidgetController()
UGasaAttributeSet* GasaAttribs = Cast<UGasaAttributeSet>( Data.Attributes );
<bindings>
AbilitySystem->Event_OnEffectAppliedAssetTags.AddUObject(this, & UHostWidgetController::OnEffectAppliedAssetTags);
})
));
}
@ -219,7 +222,7 @@ void gen_UHostWidgetController()
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(
"field", (StrC) attribute_field,

View File

@ -7,25 +7,44 @@
#include "GasaGenCommon.cpp"
#endif
void def_attribute_properties ( CodeBody body, Array<StringCached> properties );
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 );
void def_attribute_field_value_getters ( CodeBody body, Array<StringCached> properties );
void def_attribute_field_value_setters ( CodeBody body, Array<StringCached> properties );
void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, Array<StringCached> properties );
void def_attribute_field_initers ( CodeBody body, Array<StringCached> properties );
void impl_attribute_fields ( CodeBody body, StrC class_name, Array<StringCached> properties );
struct GAS_AttributeEntry
{
StringCached Name;
StringCached MinName;
StringCached MaxName;
float Min;
float Max;
};
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
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) {
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")));
StringCached str_Health = get_cached_string(txt("Health"));
StringCached str_MaxHealth = get_cached_string(txt("MaxHealth"));
StringCached str_Mana = get_cached_string(txt("Mana"));
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;
}
@ -35,7 +54,7 @@ void gen_UGasaAttributeSet()
CodeType type_UAttributeSet = def_type( txt("UAttributeSet") );
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");
@ -57,32 +76,39 @@ void gen_UGasaAttributeSet()
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_properties( body, attribute_fields);
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 )));
body.append( def_pragma(txt( "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( def_pragma(txt( "endregion Getters" )));
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 );
body.append( fmt_newline );
body.append( fmt_newline );
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( def_pragma( txt("region AttributeSet")));
body.append( code_str(
void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
void PostGameplayEffectExecute(FGameplayEffectModCallbackData const& Data) override;
));
body.append( def_pragma( txt("endregion AttributeSet")));
body.append(fmt_newline);
body.append( def_pragma( txt("region UObject")));
CodeFn GetLifetimeOfReplicatedProps = parse_function( code(
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
@ -144,6 +170,7 @@ void gen_UGasaAttributeSet()
header.print(fmt_newline);
source.print( def_include( txt("GasaAttributeSet.h")));
source.print( def_include( txt("GasaAttributeSet_Inlines.h")));
source.print( def_include( txt("EffectProperties.h")));
source.print(fmt_newline);
source.print( def_include( txt("AbilitySystemComponent.h")));
source.print( def_include( txt("Net/UnrealNetwork.h")));
@ -165,14 +192,68 @@ void gen_UGasaAttributeSet()
impl_attribute_fields( body, class_name, attribute_fields);
Code PostGameplayEffectExecute = parse_function( code(
void UGasaAttributeSet::PostGameplayEffectExecute(FGameplayEffectModCallbackData const& Data)
{
Super::PostGameplayEffectExecute(Data);
FEffectProperties Props;
Props.Populate(Data);
}
));
body.append(PostGameplayEffectExecute);
body.append(fmt_newline);
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>);
}
)));
}
attribute_clamps.append(fmt_newline);
attribute_clamps.append(fmt_newline);
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);
body.append(fmt_newline);
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)
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>);
)));
}
@ -194,44 +275,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")
FGameplayAttributeData <property>;
));
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)) );
body.append(field_uproperty);
}
}
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() );
body.append(fmt_newline);
body.append( umeta_UFUNCTION );
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 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(
token_fmt( "class_name", class_name, "property", (StrC)property,
token_fmt( "class_name", class_name, "property", (StrC)property.Name,
stringize(
static FGameplayAttribute Get<property>Attribute()
{
@ -245,11 +321,11 @@ void def_attribute_field_property_getters( CodeBody body, StrC class_name, Array
#pragma push_macro("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(
FORCEINLINE float Get<property>() const
{
@ -259,24 +335,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(
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")));
for ( String property : properties )
for ( GAS_AttributeEntry property : properties )
{
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(
FORCEINLINE void <class_name>::Set<property>(float NewVal)
{
@ -292,11 +368,11 @@ void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name
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(
FORCEINLINE void Init<property>(float NewVal)
{
@ -307,14 +383,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(def_pragma( txt("region Rep Notifies")));
for ( String property : properties )
for ( GAS_AttributeEntry property : properties )
{
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(
void <class_name>::Client_OnRep_<property>(FGameplayAttributeData& Prev<property>)
{

83
scripts/clean_shit_up.ps1 Normal file
View File

@ -0,0 +1,83 @@
# PowerShell script to set up Git LFS for Content directory
clear-host
$path_scripts = $PSScriptRoot
$path_helpers = join-path $path_scripts 'helpers'
$path_root = split-path -Parent -Path $path_scripts
$path_ue = join-path '../../Surgo' 'UE'
$path_project = join-path $path_root 'Project'
# Set your repository paths here
$path_content = join-path $path_project 'Content'
# Function to remove Content directory from Git history
function Remove-ContentFromGitHistory {
push-location $path_repo
$cgit_filter_branch = 'filter-branch'
$cgit_for_each_ref = 'for-each-ref'
$cgit_update_ref = 'update-ref'
$cgit_reflog_expire = 'reflog expire'
$cgit_garbage_collect = 'gc'
$fgit_agressive = '--aggressive'
$fgit_all = '--all'
$fgit_cached = '--cached'
$fgit_format = '--format'
$fgit_expire_now = '--expire=now'
$fgit_ignore_unmatch = '--ignore-unmatch'
$fgit_index_filter = '--index-filter'
$fgit_force = '--force'
$fgit_prune_empty = '--prune-empty'
$fgit_prune_now = '--prune=now'
$fgit_tag_name_filter = '--tag-name-filter'
$fgit_stdin = '--stdin'
$fgit_filter_concat = 'cat'
$fgit_filter_separate = '--'
$fmt_delete_refs = 'delete $(refname)'
$original_refs = 'refs/original'
$filter_cmd = 'git rm -r --cached'
# Construct filter-branch command
$filter_branch_args = @()
$filter_branch_args += $fgit_force
$filter_branch_args += $fgit_index_filter
$filter_branch_args += "git rm -r $fgit_cached $fgit_ignore_unmatch $path_content"
$filter_branch_args += $fgit_prune_empty
$filter_branch_args += $fgit_tag_name_filter
$filter_branch_args += $fgit_filter_concat
$filter_branch_args += $fgit_filter_separate
$filter_branch_args += $fgit_all
# Execute filter-branch command
& git $cgit_filter_branch $filter_branch_args
# Construct for-each-ref command
$for_each_ref_args = @()
$for_each_ref_args += "$fgit_format='$fmt_delete_refs'"
$for_each_ref_args += $original_refs
# Execute for-each-ref and pipe to update-ref
$refs_to_delete = & git $cgit_for_each_ref $for_each_ref_args
$refs_to_delete | & git $cgit_update_ref $fgit_stdin
# Construct and execute reflog expire command
$reflog_expire_args = @()
$reflog_expire_args += $fgit_expire_now
$reflog_expire_args += $fgit_all
& git $cgit_reflog_expire $reflog_expire_args
# Construct and execute garbage collect command
$gc_args = @()
$gc_args += $fgit_prune_now
$gc_args += $fgit_aggressive
& git $cgit_garbage_collect $gc_args
pop-location
}
Remove-ContentFromGitHistory

View File

@ -54,7 +54,7 @@ elseif ( $release -eq $false ) {
else {
$optimize = $true
}
#endregion Configuration
. $vendor_toolchain
. $incremental_checks
@ -103,3 +103,4 @@ function run-gengasa
Pop-Location
}
run-gengasa
#endregion Building

View File

@ -55,6 +55,21 @@
</Expand>
</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">
<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString>
<Expand>

View File

@ -0,0 +1,4 @@
clear-host