Misc Fixes

This commit is contained in:
Nyx
2025-10-05 10:12:44 -06:00
parent ebee88c92b
commit f32d8cf0d6
35 changed files with 782 additions and 286 deletions

View File

@@ -0,0 +1,57 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "AttributeSet.h"
#include "ElistriaAttributeSetBase.h"
#include "Net/UnrealNetwork.h"
#include "GameplayEffectExtension.h"
#include "HealthAttributeSet.generated.h"
/**
*
*/
UCLASS()
class ELISTRIA_CALLING_API UHealthAttributeSet : public UElistriaAttributeSetBase
{
GENERATED_BODY()
public:
UHealthAttributeSet();
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,ReplicatedUsing=OnRep_Health)
FGameplayAttributeData Health;
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,ReplicatedUsing=OnRep_MaxHealth)
FGameplayAttributeData MaxHealth;
UPROPERTY(VisibleAnywhere)
FGameplayAttributeData Damage;
UPROPERTY(VisibleAnywhere)
FGameplayAttributeData Heal;
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, Health)
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, MaxHealth)
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, Damage)
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, Heal)
UFUNCTION()
void OnRep_Health(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MaxHealth(const FGameplayAttributeData& OldValue);
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnHealthChanged;
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnMaxHealthChanged;
};

View File

@@ -0,0 +1,76 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "ElistriaAttributeSetBase.h"
#include "AbilitySystemComponent.h"
#include "Net/UnrealNetwork.h"
#include "GameplayEffectExtension.h"
#include "ManaAttributeSet.h"
#include "LevelAttributeSet.generated.h"
/**
*
*/
UCLASS()
class ELISTRIA_CALLING_API ULevelAttributeSet : public UElistriaAttributeSetBase
{
GENERATED_BODY()
public:
ULevelAttributeSet();
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_Level)
FGameplayAttributeData Level;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_XP)
FGameplayAttributeData XP;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing = OnRep_XPToNextLevel)
FGameplayAttributeData XPToNextLevel;
UPROPERTY(VisibleAnywhere)
FGameplayAttributeData XPGain;
UPROPERTY(VisibleAnywhere)
FGameplayAttributeData XPLoss;
UPROPERTY(VisibleAnywhere)
FGameplayAttributeData MaxLevel;
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XP)
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, Level)
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, MaxLevel)
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XPToNextLevel)
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XPGain)
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XPLoss)
UFUNCTION()
void OnRep_Level(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_XP(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_XPToNextLevel(const FGameplayAttributeData& OldValue);
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnLevelChanged;
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnXPChanged;
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnXPToNextLevelChanged;
protected:
float ComputeXPForLevel(int32 InLevel) const;
void HandleLevelUp(int32 LevelsGained);
void ConsumeXPGain();
void TryProcessLevelUp();
};

View File

@@ -3,8 +3,8 @@
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "ElistriaAttributeSetBase.h"
#include "Net/UnrealNetwork.h"
#include "GameplayEffectExtension.h"
#include "ManaAttributeSet.generated.h"
@@ -13,16 +13,8 @@
*
*/
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAttributeChangedEvent, UAttributeSet*, AttributeSet, float, OldValue, float, NewValue);
UCLASS()
class ELISTRIA_CALLING_API UManaAttributeSet : public UAttributeSet
class ELISTRIA_CALLING_API UManaAttributeSet : public UElistriaAttributeSetBase
{
GENERATED_BODY()

View File

@@ -0,0 +1,53 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "ElistriaAttributeSetBase.h"
#include "HealthAttributeSet.h"
#include "StaminaAttributeSet.generated.h"
/**
*
*/
UCLASS()
class ELISTRIA_CALLING_API UStaminaAttributeSet : public UElistriaAttributeSetBase
{
GENERATED_BODY()
public:
UStaminaAttributeSet();
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_Stamina)
FGameplayAttributeData Stamina;
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, Stamina)
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_MaxStamina)
FGameplayAttributeData MaxStamina;
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, MaxStamina)
UPROPERTY(VisibleAnywhere)
FGameplayAttributeData Drain;
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, Drain)
UPROPERTY(VisibleAnywhere)
FGameplayAttributeData Restore;
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, Restore)
UFUNCTION()
void OnRep_Stamina(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MaxStamina(const FGameplayAttributeData& OldValue);
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnStaminaChanged;
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnMaxStaminaChanged;
};

View File

@@ -11,35 +11,36 @@
/**
*
*/
class UPlayerGameplayAbilitiesDataAsset;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnASCGrantedInputAbilties, UElistriaAbilitySystemComponent*, ASC);
UCLASS()
class ELISTRIA_CALLING_API UElistriaAbilitySystemComponent : public UAbilitySystemComponent
{
GENERATED_BODY()
public:
UFUNCTION(Server, Reliable)
void ServerActivateAbilityByInputID(FGameplayAbilitySpecHandle Handle, int32 InputID);
UPROPERTY(BlueprintAssignable, Category="AbilitySystem")
FOnASCGrantedInputAbilties OnGrantedInputAbilties;
UFUNCTION(BlueprintCallable)
void EquipAbility(TSubclassOf<UGameplayAbility> NewAbility, int32 SlotIndex);
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
void GrantAbilitiesFromDataAsset(const UPlayerGameplayAbilitiesDataAsset* AbilitiesDataAsset);
UFUNCTION(BlueprintCallable)
void UnequipAbility(int32 SlotIndex);
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
void HandleInputTag(ETriggerEvent EventType, FGameplayTag InputTag);
void RefreshInputBindings();
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
void ConfirmTargetingInput(){TargetConfirm();}
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
void CancelTargetingInput(){TargetCancel();}
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAbilitiesChanged, UElistriaAbilitySystemComponent*, ASC);
UPROPERTY(BlueprintAssignable)
FOnAbilitiesChanged OnAbilitiesChanged;
void GrantAbilitiesFromDataAsset(const UPlayerGameplayAbilitiesDataAsset* AbilitiesDataAsset);
virtual void AbilityLocalInputPressed(int32 InputID) override;
private:
TMap<int32, FGameplayAbilitySpecHandle> InputIDToAbilitySpecHandleMap;
UPROPERTY()
TMap<int32, FGameplayAbilitySpecHandle> SlotToAbilityHandleMap;
void ServerActivateAbilityByInputID_Implementation(FGameplayAbilitySpecHandle Handle, int32 InputID);
TMap<FGameplayTag, FGameplayAbilitySpecHandle> TagToSpecHandleMap;
};

View File

@@ -0,0 +1,24 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "ElistriaAttributeSetBase.generated.h"
/**
*
*/
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAttributeChangedEvent, UAttributeSet*, AttributeSet, float, OldValue, float, NewValue);
UCLASS()
class ELISTRIA_CALLING_API UElistriaAttributeSetBase : public UAttributeSet
{
GENERATED_BODY()
};

View File

@@ -14,26 +14,42 @@ UCLASS()
class ELISTRIA_CALLING_API UElistriaEnhancedInputComponent : public UEnhancedInputComponent
{
GENERATED_BODY()
public:
template<class UserClass, typename FuncType>
void BindAbilityActions(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, FuncType Func);
public:
template <class UserClass>
void BindAbilityActionsByTag(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object,
void (UserClass::*Func)(const FInputActionInstance&, FGameplayTag));
UFUNCTION(BlueprintCallable, Category="Input")
void ClearAbilityBindings();
private:
TArray<uint32> AbilityActionBindings;
TArray<int32> AbilityActionBindings;
};
template<class UserClass, typename FuncType>
void UElistriaEnhancedInputComponent::BindAbilityActions(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, FuncType Func)
template <class UserClass>
void UElistriaEnhancedInputComponent::BindAbilityActionsByTag(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, void (UserClass::*Func)(const FInputActionInstance&, FGameplayTag))
{
if (!InputConfig) return;
if (!InputConfig||!Func) return;
for (const FGameplayInputAbilityInfo& AbilityInfo : InputConfig->GetInputAbilities())
static const ETriggerEvent EventsToBind[]={
ETriggerEvent::Started,
ETriggerEvent::Completed,
ETriggerEvent::Canceled,
ETriggerEvent::Triggered,
ETriggerEvent::Ongoing
};
for (const FGameplayInputAbilityInfo& Info : InputConfig->AbilityMappings)
{
if (AbilityInfo.IsValid())
if (!Info.IsValid()) continue;
for (ETriggerEvent Event : EventsToBind)
{
BindAction(AbilityInfo.InputAction,ETriggerEvent::Triggered,Object,Func,AbilityInfo.InputID);
FEnhancedInputActionEventBinding& Binding = BindAction(Info.InputAction,Event,Object,Func,Info.InputTag);
AbilityActionBindings.Add(Binding.GetHandle());
}
}
}
{
}
}

View File

@@ -1,17 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "HealthAttributeSet.generated.h"
/**
*
*/
UCLASS()
class ELISTRIA_CALLING_API UHealthAttributeSet : public UAttributeSet
{
GENERATED_BODY()
};

View File

@@ -7,35 +7,50 @@
#include "GameFramework/PlayerController.h"
#include "InputMappingContext.h"
#include "EnhancedInputSubsystems.h"
#include "ElistriaEnhancedInputComponent.h"
class UPlayerGameplayAbilitiesDataAsset;
class UInputMappingContext;
class UElistriaEnhancedInputComponent;
class UElistriaAbilitySystemComponent;
class AMagickPlayerState;
struct FInputActionInstance;
#include "MagickPlayerController.generated.h"
/**
*
*/
UCLASS()
class ELISTRIA_CALLING_API AMagickPlayerController : public APlayerController
{
GENERATED_BODY()
virtual void OnPossess(APawn* InPawn) override;
public:
virtual void SetupInputComponent() override;
virtual void OnPossess(APawn* InPawn) override;
virtual void BeginPlay() override;
UFUNCTION(BlueprintCallable, Category="Input")
void RebindAbilityInputs();
UFUNCTION()
void OnASCGranted(UElistriaAbilitySystemComponent* ASC);
UFUNCTION()
void HandleInput(const FInputActionInstance& Instance, FGameplayTag InputTag);
UFUNCTION()
void OnAbilitiesChanged(UElistriaAbilitySystemComponent* ASC);
public:
UFUNCTION()
void AbilityInputTag(const FInputActionInstance& Instance, FGameplayTag InputTag);
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Input")
TObjectPtr<UPlayerGameplayAbilitiesDataAsset> InputAbilitiesDataAsset;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Input")
TObjectPtr<UInputMappingContext> InputMappingContext;
virtual void SetupInputComponent() override;
UFUNCTION()
void AbilityInputPressed(int32 InputID);
virtual void BeginPlay() override;
void RebindAbilityInputs();
};

View File

@@ -6,8 +6,13 @@
#include "GameFramework/PlayerState.h"
#include "AbilitySystemInterface.h"
#include "ElistriaAbilitySystemComponent.h"
#include "ManaAttributeSet.h"
#include "MagickPlayerController.h"
#include "Attributes/ManaAttributeSet.h"
#include "Attributes/StaminaAttributeSet.h"
#include "Attributes/HealthAttributeSet.h"
#include "Attributes/LevelAttributeSet.h"
class AMagickPlayerController;
#include "MagickPlayerState.generated.h"
UCLASS(Config=game)
@@ -15,8 +20,6 @@ class ELISTRIA_CALLING_API AMagickPlayerState : public APlayerState, public IAbi
{
GENERATED_BODY()
virtual void BeginPlay() override;
public:
@@ -34,6 +37,15 @@ protected:
UPROPERTY(Replicated)
TObjectPtr<class UManaAttributeSet> ManaSet;
UPROPERTY(Replicated)
TObjectPtr<UStaminaAttributeSet> StaminaSet;
UPROPERTY(Replicated)
TObjectPtr<UHealthAttributeSet> HealthSet;
UPROPERTY(Replicated)
TObjectPtr<ULevelAttributeSet> LevelSet;
private:
};

View File

@@ -12,43 +12,32 @@
*/
class UInputAction;
USTRUCT()
USTRUCT(BlueprintType)
struct FGameplayInputAbilityInfo
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, Category = "GameplayInputAbilityInfo")
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ability")
TSubclassOf<UGameplayAbility> AbilityClass;
UPROPERTY(EditAnywhere, Category = "GameplayInputAbilityInfo")
UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Ability")
TObjectPtr<UInputAction> InputAction;
UPROPERTY(VisibleAnywhere, Category = "GameplayInputAbilityInfo")
int32 InputID;
UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Ability", meta = (Categories="Input"))
FGameplayTag InputTag;
bool IsValid() const
UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Ability")
bool bAutoGive = true;
bool IsValid() const{ return AbilityClass && InputAction && InputTag.IsValid();}
bool operator==(const FGameplayInputAbilityInfo& Other) const
{
return AbilityClass && InputAction;
return AbilityClass == Other.AbilityClass && InputAction == Other.InputAction && InputTag == Other.InputTag;
}
bool operator==(const FGameplayInputAbilityInfo& other) const
{
return AbilityClass == other.AbilityClass && InputID == other.InputID;
}
bool operator!=(const FGameplayInputAbilityInfo& other) const
{
return !operator==(other);
}
friend uint32 GetTypeHash(const FGameplayInputAbilityInfo& Item)
{
return HashCombine(GetTypeHash(Item.AbilityClass), Item.InputID);
}
FGameplayInputAbilityInfo()
: InputID(INDEX_NONE)
{
return HashCombine(GetTypeHash(Item.AbilityClass), GetTypeHash(Item.InputTag));
}
};
@@ -57,16 +46,44 @@ class ELISTRIA_CALLING_API UPlayerGameplayAbilitiesDataAsset : public UDataAsset
{
GENERATED_BODY()
protected:
UPROPERTY(EditAnywhere, Category = "AbilitySystem")
TSet<FGameplayInputAbilityInfo> InputAbilities;
public:
UPlayerGameplayAbilitiesDataAsset(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
const TSet<FGameplayInputAbilityInfo>& GetInputAbilities() const;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="AbilitySystem")
TArray<FGameplayInputAbilityInfo> AbilityMappings;
UFUNCTION(BlueprintPure, Category = "AbilitySystem")
void GetAllMappings(TArray<FGameplayInputAbilityInfo>& Out) const { Out = AbilityMappings; }
UFUNCTION(BlueprintCallable, Category = "AbilitySystem")
void AddMapping(const FGameplayInputAbilityInfo& Entry)
{
if (!Entry.IsValid()) return;
AbilityMappings.Add(Entry);
}
UFUNCTION(BlueprintCallable, Category = "AbilitySystem")
void RemoveByTag(FGameplayTag InputTag)
{
AbilityMappings.RemoveAll([&](const FGameplayInputAbilityInfo& E) { return E.InputTag == InputTag; });
}
UFUNCTION(BlueprintPure, Category = "AbilitySystem")
void FindByTag(FGameplayTag InputTag, TArray<FGameplayInputAbilityInfo>& Out) const
{
for (const auto& E : AbilityMappings)
{
if (E.InputTag == InputTag)
{
Out.Add(E);
}
}
}
const TArray<FGameplayInputAbilityInfo>& GetMappings() const { return AbilityMappings; }
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override
{
Super::PostEditChangeProperty(PropertyChangedEvent);
// Ensure uniqueness (Set already helps). Could add validation if needed.
}
#endif
};