// 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 AbilityType; // Input action to bind the ability to, if any (can be left unset) // UPROPERTY(EditAnywhere, BlueprintReadOnly) // TSoftObjectPtr InputAction; }; USTRUCT(BlueprintType) struct FLyraAttributeSetGrant { GENERATED_BODY() // Ability set to grant UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AssetBundles="Client,Server")) TSoftClassPtr AttributeSetType; // Data table referent to initialize the attributes with, if any (can be left unset) UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AssetBundles="Client,Server")) TSoftObjectPtr InitializationData; }; USTRUCT() struct FGameFeatureAbilitiesEntry { GENERATED_BODY() // The base actor class to add to UPROPERTY(EditAnywhere, Category="Abilities") TSoftClassPtr ActorClass; // List of abilities to grant to actors of the specified class UPROPERTY(EditAnywhere, Category="Abilities") TArray GrantedAbilities; // List of attribute sets to grant to actors of the specified class UPROPERTY(EditAnywhere, Category="Attributes") TArray GrantedAttributes; // List of ability sets to grant to actors of the specified class UPROPERTY(EditAnywhere, Category="Attributes", meta=(AssetBundles="Client,Server")) TArray> 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& ValidationErrors) override; #endif //~ End UObject interface /** */ UPROPERTY(EditAnywhere, Category="Abilities", meta=(TitleProperty="ActorClass", ShowOnlyInnerProperties)) TArray AbilitiesList; private: struct FActorExtensions { TArray Abilities; TArray Attributes; TArray AbilitySetHandles; }; struct FPerContextData { TMap ActiveExtensions; TArray> ComponentRequests; }; TMap 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 ComponentType* FindOrAddComponentForActor(AActor* Actor, const FGameFeatureAbilitiesEntry& AbilitiesEntry, FPerContextData& ActiveData) { //@TODO: Just find, no add? return Cast(FindOrAddComponentForActor(ComponentType::StaticClass(), Actor, AbilitiesEntry, ActiveData)); } UActorComponent* FindOrAddComponentForActor(UClass* ComponentType, AActor* Actor, const FGameFeatureAbilitiesEntry& AbilitiesEntry, FPerContextData& ActiveData); };