// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action. #include "DataAssets/OLSAbilitySetDataAsset.h" #include "ActiveGameplayEffectHandle.h" #include "GameplayAbilitySpecHandle.h" #include "OLSLog.h" #include "AbilitySystem/OLSAbilitySystemComponent.h" #include "AbilitySystem/Abilities/OLSGameplayAbility.h" #include "AbilitySystem/Attributes/OLSAttributeSetBase.h" DEFINE_LOG_CATEGORY(LogOLSAbilitySetDataAsset); void FOLSAbilitySet_GrantedHandles::AddAbilitySpecHandle(const FGameplayAbilitySpecHandle& handle) { if (handle.IsValid()) { AbilitySpecHandles.Add(handle); } } void FOLSAbilitySet_GrantedHandles::AddGameplayEffectHandle(const FActiveGameplayEffectHandle& handle) { if (handle.IsValid()) { GameplayEffectHandles.Add(handle); } } void FOLSAbilitySet_GrantedHandles::AddAttributeSet(UAttributeSet* set) { GrantedAttributeSets.Add(set); } void FOLSAbilitySet_GrantedHandles::TakeFromAbilitySystem(UOLSAbilitySystemComponent* olsASC) { check(olsASC); if (!olsASC->IsOwnerActorAuthoritative()) { // Must be authoritative to give or take ability sets. return; } for (const FGameplayAbilitySpecHandle& handle : AbilitySpecHandles) { if (handle.IsValid()) { olsASC->ClearAbility(handle); } } for (const FActiveGameplayEffectHandle& handle : GameplayEffectHandles) { if (handle.IsValid()) { olsASC->RemoveActiveGameplayEffect(handle); } } for (UAttributeSet* set : GrantedAttributeSets) { olsASC->RemoveSpawnedAttribute(set); } AbilitySpecHandles.Reset(); GameplayEffectHandles.Reset(); GrantedAttributeSets.Reset(); } UOLSAbilitySetDataAsset::UOLSAbilitySetDataAsset(const FObjectInitializer& objectInitializer) : Super(objectInitializer) { } void UOLSAbilitySetDataAsset::GiveToAbilitySystem( UOLSAbilitySystemComponent* olsASC, FOLSAbilitySet_GrantedHandles* outGrantedHandlePtrs, UObject* sourceObject) const { check(olsASC); if (!olsASC->IsOwnerActorAuthoritative()) { // Must be authoritative to give or take ability sets. return; } // Grant the attribute sets. for (int32 setIndex = 0; setIndex < GrantedAttributes.Num(); ++setIndex) { const FOLSAbilitySet_AttributeSet& setToGrant = GrantedAttributes[setIndex]; if (!IsValid(setToGrant.AttributeSet)) { OLS_LOG(LogOLSAbilitySetDataAsset, Error, TEXT("GrantedAttributes[%d] on ability set [%s] is not valid"), setIndex, GET_UOBJECT_NAME(this)); continue; } UAttributeSet* newSet = NewObject(olsASC->GetOwner(), setToGrant.AttributeSet); olsASC->AddAttributeSetSubobject(newSet); if (outGrantedHandlePtrs) { outGrantedHandlePtrs->AddAttributeSet(newSet); } } // Grant the gameplay abilities. for (int32 abilityIndex = 0; abilityIndex < GrantedGameplayAbilities.Num(); ++abilityIndex) { const FOLSAbilitySet_GameplayAbility& AbilityToGrant = GrantedGameplayAbilities[abilityIndex]; if (!IsValid(AbilityToGrant.Ability)) { OLS_LOG(LogOLSAbilitySetDataAsset, Error, TEXT("GrantedGameplayAbilities[%d] on ability set [%s] is not valid"), abilityIndex, GET_UOBJECT_NAME(this)); continue; } UOLSGameplayAbility* abilityCDO = AbilityToGrant.Ability->GetDefaultObject(); FGameplayAbilitySpec abilitySpec(abilityCDO, AbilityToGrant.AbilityLevel); abilitySpec.SourceObject = sourceObject; abilitySpec.GetDynamicSpecSourceTags().AddTag(AbilityToGrant.InputTag); const FGameplayAbilitySpecHandle abilitySpecHandle = olsASC->GiveAbility(abilitySpec); if (outGrantedHandlePtrs) { outGrantedHandlePtrs->AddAbilitySpecHandle(abilitySpecHandle); } } // Grant the gameplay effects. for (int32 effectIndex = 0; effectIndex < GrantedGameplayEffects.Num(); ++effectIndex) { const FOLSAbilitySet_GameplayEffect& EffectToGrant = GrantedGameplayEffects[effectIndex]; if (!IsValid(EffectToGrant.GameplayEffect)) { OLS_LOG(LogOLSAbilitySetDataAsset, Error, TEXT("GrantedGameplayEffects[%d] on ability set [%s] is not valid"), effectIndex, GET_UOBJECT_NAME(this)); continue; } const UGameplayEffect* gameplayEffect = EffectToGrant.GameplayEffect->GetDefaultObject(); const FActiveGameplayEffectHandle gameplayEffectHandle = olsASC->ApplyGameplayEffectToSelf(gameplayEffect, EffectToGrant.EffectLevel, olsASC->MakeEffectContext()); if (outGrantedHandlePtrs) { outGrantedHandlePtrs->AddGameplayEffectHandle(gameplayEffectHandle); } } }