// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action. #pragma once #include "CoreMinimal.h" #include "Abilities/GameplayAbility.h" #include "OLSGameplayAbility.generated.h" DECLARE_LOG_CATEGORY_EXTERN(LogOLSGameplayAbility, Verbose, All); /** * ELyraAbilityActivationPolicy * * Defines how an ability is meant to activate. */ UENUM(BlueprintType) enum class EOLSAbilityActivationPolicy : uint8 { // Try to activate the ability when the input is triggered. OnInputTriggered, // Continually try to activate the ability while the input is active. WhileInputActive, // Try to activate the ability when an avatar is assigned. OnSpawn }; /** * ELyraAbilityActivationGroup * * Defines how an ability activates in relation to other abilities. */ UENUM(BlueprintType) enum class EOLSAbilityActivationGroup : uint8 { // Ability runs independently of all other abilities. Independent, // Ability is canceled and replaced by other exclusive abilities. Exclusive_Replaceable, // Ability blocks all other exclusive abilities from activating. Exclusive_Blocking, MAX UMETA(Hidden) }; /** Failure reason that can be used to play an animation montage when a failure occurs */ USTRUCT(BlueprintType) struct FOLSAbilityMontageFailureMessage { GENERATED_BODY() public: // Player controller that failed to activate the ability, if the AbilitySystemComponent was player owned UPROPERTY(BlueprintReadWrite) TObjectPtr PlayerController = nullptr; // Avatar actor that failed to activate the ability UPROPERTY(BlueprintReadWrite) TObjectPtr AvatarActor = nullptr; // All the reasons why this ability has failed UPROPERTY(BlueprintReadWrite) FGameplayTagContainer FailureTags; UPROPERTY(BlueprintReadWrite) TObjectPtr FailureMontage = nullptr; }; /** * UOLSGameplayAbility * * The base gameplay ability class used by this project. */ UCLASS(Abstract, HideCategories = Input, Meta = (ShortTooltip = "The base gameplay ability class used by this project.")) class OLS_API UOLSGameplayAbility : public UGameplayAbility { GENERATED_BODY() public: UOLSGameplayAbility(const FObjectInitializer& objectInitializer); protected: //~UGameplayAbility interface virtual bool CanActivateAbility(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo, const FGameplayTagContainer* sourceTags, const FGameplayTagContainer* targetTags, FGameplayTagContainer* optionalRelevantTags) const override; virtual void SetCanBeCanceled(bool canBeCanceled) override; virtual void OnGiveAbility(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec) override; virtual void OnRemoveAbility(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec) override; virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override; virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override; virtual bool CheckCost(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo, OUT FGameplayTagContainer* optionalRelevantTags = nullptr) const override; virtual void ApplyCost(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilityActivationInfo activationInfo) const override; virtual FGameplayEffectContextHandle MakeEffectContext(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo) const override; virtual void ApplyAbilityTagsToGameplayEffectSpec(FGameplayEffectSpec& spec, FGameplayAbilitySpec* abilitySpec) const override; virtual bool DoesAbilitySatisfyTagRequirements(const UAbilitySystemComponent& abilitySystemComponent, const FGameplayTagContainer* sourceTags = nullptr, const FGameplayTagContainer* targetTags = nullptr, OUT FGameplayTagContainer* optionalRelevantTags = nullptr) const override; //~End of UGameplayAbility interface public: UFUNCTION(BlueprintCallable, Category = "OLS|Ability") class UOLSAbilitySystemComponent* GetOLSAbilitySystemComponentFromActorInfo() const; UFUNCTION(BlueprintCallable, Category = "OLS|Ability") AController* GetControllerFromActorInfo() const; UFUNCTION(BlueprintCallable, Category = "Lyra|Ability") class UOLSHeroComponent* GetHeroComponentFromActorInfo() const; // Returns true if the requested activation group is a valid transition. UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "OLS|Ability", Meta = (ExpandBoolAsExecs = "ReturnValue")) bool CanChangeActivationGroup(EOLSAbilityActivationGroup newGroup) const; // Tries to change the activation group. Returns true if it successfully changed. UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "OLS|Ability", Meta = (ExpandBoolAsExecs = "ReturnValue")) bool ChangeActivationGroup(EOLSAbilityActivationGroup newGroup); // Sets the ability's camera mode. UFUNCTION(BlueprintCallable, Category = "Lyra|Ability") void SetCameraMode(TSubclassOf cameraMode); // Clears the ability's camera mode. Automatically called if needed when the ability ends. UFUNCTION(BlueprintCallable, Category = "Lyra|Ability") void ClearCameraMode(); public: EOLSAbilityActivationPolicy GetActivationPolicy() const; EOLSAbilityActivationGroup GetActivationGroup() const; void TryActivateAbilityOnSpawn(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec) const; void OnAbilityFailedToActivate(const FGameplayTagContainer& failedReason) const; protected: virtual void OnPawnAvatarSet(); virtual void GetAbilitySource(FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo, float& outSourceLevel, const class IOLSAbilitySourceInterface*& outAbilitySource, AActor*& outEffectCauser) const; // Called when the ability fails to activate virtual void NativeOnAbilityFailedToActivate(const FGameplayTagContainer& failedReason) const; // Called when the ability fails to activate UFUNCTION(BlueprintImplementableEvent, DisplayName = "OnAbilityFailedToActivate") void K2_OnAbilityFailedToActivate(const FGameplayTagContainer& FailedReason) const; /** Called when this ability is granted to the ability system component. */ UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "OnAbilityAdded") void K2_OnAbilityAdded(); /** Called when this ability is removed from the ability system component. */ UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "OnAbilityRemoved") void K2_OnAbilityRemoved(); /** Called when the ability system is initialized with a pawn avatar. */ UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "OnPawnAvatarSet") void K2_OnPawnAvatarSet(); protected: // Defines how this ability is meant to activate. UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "OLS|Ability Activation") EOLSAbilityActivationPolicy ActivationPolicy; // Defines the relationship between this ability activating and other abilities activating. UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "OLS|Ability Activation") EOLSAbilityActivationGroup ActivationGroup; // Additional costs that must be paid to activate this ability UPROPERTY(EditDefaultsOnly, Instanced, Category = Costs) TArray> AdditionalCosts; // Map of failure tags to simple error messages UPROPERTY(EditDefaultsOnly, Category = "Advanced") TMap FailureTagToUserFacingMessages; // Map of failure tags to anim montages that should be played with them UPROPERTY(EditDefaultsOnly, Category = "Advanced") TMap> FailureTagToAnimMontage; // If true, extra information should be logged when this ability is canceled. This is temporary, used for tracking a bug. UPROPERTY(EditDefaultsOnly, Category = "Advanced") uint8 bShouldLogCancellation : 1 = false; // Current camera mode set by the ability. TSubclassOf ActiveCameraMode; };