RealtimeStyleTransferRuntime/Source/LyraGame/GameFeatures/GameFeatureAction_AddAbilit...

129 lines
4.5 KiB
C
Raw Normal View History

2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFeatureAction_WorldActionBase.h"
#include "Abilities/GameplayAbility.h"
#include "AbilitySystem/LyraAbilitySet.h"
#include "GameFeatureAction_AddAbilities.generated.h"
struct FWorldContext;
class UInputAction;
class UAttributeSet;
class UDataTable;
struct FComponentRequestHandle;
class ULyraAbilitySet;
USTRUCT(BlueprintType)
struct FLyraAbilityGrant
{
GENERATED_BODY()
// Type of ability to grant
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AssetBundles="Client,Server"))
TSoftClassPtr<UGameplayAbility> AbilityType;
// Input action to bind the ability to, if any (can be left unset)
// UPROPERTY(EditAnywhere, BlueprintReadOnly)
// TSoftObjectPtr<UInputAction> InputAction;
};
USTRUCT(BlueprintType)
struct FLyraAttributeSetGrant
{
GENERATED_BODY()
// Ability set to grant
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AssetBundles="Client,Server"))
TSoftClassPtr<UAttributeSet> AttributeSetType;
// Data table referent to initialize the attributes with, if any (can be left unset)
UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AssetBundles="Client,Server"))
TSoftObjectPtr<UDataTable> InitializationData;
};
USTRUCT()
struct FGameFeatureAbilitiesEntry
{
GENERATED_BODY()
// The base actor class to add to
UPROPERTY(EditAnywhere, Category="Abilities")
TSoftClassPtr<AActor> ActorClass;
// List of abilities to grant to actors of the specified class
UPROPERTY(EditAnywhere, Category="Abilities")
TArray<FLyraAbilityGrant> GrantedAbilities;
// List of attribute sets to grant to actors of the specified class
UPROPERTY(EditAnywhere, Category="Attributes")
TArray<FLyraAttributeSetGrant> GrantedAttributes;
// List of ability sets to grant to actors of the specified class
UPROPERTY(EditAnywhere, Category="Attributes", meta=(AssetBundles="Client,Server"))
TArray<TSoftObjectPtr<const ULyraAbilitySet>> GrantedAbilitySets;
};
//////////////////////////////////////////////////////////////////////
// UGameFeatureAction_AddAbilities
/**
* GameFeatureAction responsible for granting abilities (and attributes) to actors of a specified type.
*/
UCLASS(MinimalAPI, meta = (DisplayName = "Add Abilities"))
class UGameFeatureAction_AddAbilities final : public UGameFeatureAction_WorldActionBase
{
GENERATED_BODY()
public:
//~ Begin UGameFeatureAction interface
virtual void OnGameFeatureActivating(FGameFeatureActivatingContext& Context) override;
virtual void OnGameFeatureDeactivating(FGameFeatureDeactivatingContext& Context) override;
//~ End UGameFeatureAction interface
//~ Begin UObject interface
#if WITH_EDITOR
virtual EDataValidationResult IsDataValid(TArray<FText>& ValidationErrors) override;
#endif
//~ End UObject interface
/** */
UPROPERTY(EditAnywhere, Category="Abilities", meta=(TitleProperty="ActorClass", ShowOnlyInnerProperties))
TArray<FGameFeatureAbilitiesEntry> AbilitiesList;
private:
struct FActorExtensions
{
TArray<FGameplayAbilitySpecHandle> Abilities;
TArray<UAttributeSet*> Attributes;
TArray<FLyraAbilitySet_GrantedHandles> AbilitySetHandles;
};
struct FPerContextData
{
TMap<AActor*, FActorExtensions> ActiveExtensions;
TArray<TSharedPtr<FComponentRequestHandle>> ComponentRequests;
};
TMap<FGameFeatureStateChangeContext, FPerContextData> ContextData;
//~ Begin UGameFeatureAction_WorldActionBase interface
virtual void AddToWorld(const FWorldContext& WorldContext, const FGameFeatureStateChangeContext& ChangeContext) override;
//~ End UGameFeatureAction_WorldActionBase interface
void Reset(FPerContextData& ActiveData);
void HandleActorExtension(AActor* Actor, FName EventName, int32 EntryIndex, FGameFeatureStateChangeContext ChangeContext);
void AddActorAbilities(AActor* Actor, const FGameFeatureAbilitiesEntry& AbilitiesEntry, FPerContextData& ActiveData);
void RemoveActorAbilities(AActor* Actor, FPerContextData& ActiveData);
template<class ComponentType>
ComponentType* FindOrAddComponentForActor(AActor* Actor, const FGameFeatureAbilitiesEntry& AbilitiesEntry, FPerContextData& ActiveData)
{
//@TODO: Just find, no add?
return Cast<ComponentType>(FindOrAddComponentForActor(ComponentType::StaticClass(), Actor, AbilitiesEntry, ActiveData));
}
UActorComponent* FindOrAddComponentForActor(UClass* ComponentType, AActor* Actor, const FGameFeatureAbilitiesEntry& AbilitiesEntry, FPerContextData& ActiveData);
};