// Copyright Epic Games, Inc. All Rights Reserved. #include "LyraAbilitySet.h" #include "Abilities/LyraGameplayAbility.h" #include "AttributeSet.h" #include "Containers/UnrealString.h" #include "GameFramework/Actor.h" #include "GameplayEffect.h" #include "Logging/LogCategory.h" #include "Logging/LogMacros.h" #include "LyraAbilitySystemComponent.h" #include "LyraLogChannels.h" #include "Misc/AssertionMacros.h" #include "Templates/ChooseClass.h" #include "Trace/Detail/Channel.h" #include "UObject/Object.h" #include "UObject/UObjectBaseUtility.h" void FLyraAbilitySet_GrantedHandles::AddAbilitySpecHandle(const FGameplayAbilitySpecHandle& Handle) { if (Handle.IsValid()) { AbilitySpecHandles.Add(Handle); } } void FLyraAbilitySet_GrantedHandles::AddGameplayEffectHandle(const FActiveGameplayEffectHandle& Handle) { if (Handle.IsValid()) { GameplayEffectHandles.Add(Handle); } } void FLyraAbilitySet_GrantedHandles::AddAttributeSet(UAttributeSet* Set) { GrantedAttributeSets.Add(Set); } void FLyraAbilitySet_GrantedHandles::TakeFromAbilitySystem(ULyraAbilitySystemComponent* LyraASC) { check(LyraASC); if (!LyraASC->IsOwnerActorAuthoritative()) { // Must be authoritative to give or take ability sets. return; } for (const FGameplayAbilitySpecHandle& Handle : AbilitySpecHandles) { if (Handle.IsValid()) { LyraASC->ClearAbility(Handle); } } for (const FActiveGameplayEffectHandle& Handle : GameplayEffectHandles) { if (Handle.IsValid()) { LyraASC->RemoveActiveGameplayEffect(Handle); } } for (UAttributeSet* Set : GrantedAttributeSets) { LyraASC->RemoveSpawnedAttribute(Set); } AbilitySpecHandles.Reset(); GameplayEffectHandles.Reset(); GrantedAttributeSets.Reset(); } ULyraAbilitySet::ULyraAbilitySet(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } void ULyraAbilitySet::GiveToAbilitySystem(ULyraAbilitySystemComponent* LyraASC, FLyraAbilitySet_GrantedHandles* OutGrantedHandles, UObject* SourceObject) const { check(LyraASC); if (!LyraASC->IsOwnerActorAuthoritative()) { // Must be authoritative to give or take ability sets. return; } // Grant the gameplay abilities. for (int32 AbilityIndex = 0; AbilityIndex < GrantedGameplayAbilities.Num(); ++AbilityIndex) { const FLyraAbilitySet_GameplayAbility& AbilityToGrant = GrantedGameplayAbilities[AbilityIndex]; if (!IsValid(AbilityToGrant.Ability)) { UE_LOG(LogLyraAbilitySystem, Error, TEXT("GrantedGameplayAbilities[%d] on ability set [%s] is not valid."), AbilityIndex, *GetNameSafe(this)); continue; } ULyraGameplayAbility* AbilityCDO = AbilityToGrant.Ability->GetDefaultObject(); FGameplayAbilitySpec AbilitySpec(AbilityCDO, AbilityToGrant.AbilityLevel); AbilitySpec.SourceObject = SourceObject; AbilitySpec.DynamicAbilityTags.AddTag(AbilityToGrant.InputTag); const FGameplayAbilitySpecHandle AbilitySpecHandle = LyraASC->GiveAbility(AbilitySpec); if (OutGrantedHandles) { OutGrantedHandles->AddAbilitySpecHandle(AbilitySpecHandle); } } // Grant the gameplay effects. for (int32 EffectIndex = 0; EffectIndex < GrantedGameplayEffects.Num(); ++EffectIndex) { const FLyraAbilitySet_GameplayEffect& EffectToGrant = GrantedGameplayEffects[EffectIndex]; if (!IsValid(EffectToGrant.GameplayEffect)) { UE_LOG(LogLyraAbilitySystem, Error, TEXT("GrantedGameplayEffects[%d] on ability set [%s] is not valid"), EffectIndex, *GetNameSafe(this)); continue; } const UGameplayEffect* GameplayEffect = EffectToGrant.GameplayEffect->GetDefaultObject(); const FActiveGameplayEffectHandle GameplayEffectHandle = LyraASC->ApplyGameplayEffectToSelf(GameplayEffect, EffectToGrant.EffectLevel, LyraASC->MakeEffectContext()); if (OutGrantedHandles) { OutGrantedHandles->AddGameplayEffectHandle(GameplayEffectHandle); } } // Grant the attribute sets. for (int32 SetIndex = 0; SetIndex < GrantedAttributes.Num(); ++SetIndex) { const FLyraAbilitySet_AttributeSet& SetToGrant = GrantedAttributes[SetIndex]; if (!IsValid(SetToGrant.AttributeSet)) { UE_LOG(LogLyraAbilitySystem, Error, TEXT("GrantedAttributes[%d] on ability set [%s] is not valid"), SetIndex, *GetNameSafe(this)); continue; } UAttributeSet* NewSet = NewObject(LyraASC->GetOwner(), SetToGrant.AttributeSet); LyraASC->AddAttributeSetSubobject(NewSet); if (OutGrantedHandles) { OutGrantedHandles->AddAttributeSet(NewSet); } } }