Let's talk

GKLGameplayAbility.cpp

Source/GASKitLite/Private/GKLGameplayAbility.cpp Raw Download ZIP

Click a line number to link it. Shift-click to select a range.

1// Copyright (c) 2026 Reignance Studios. MIT License, see LICENSE.
2
3#include "GKLGameplayAbility.h"
4
5#include "AbilitySystemComponent.h"
6#include "AbilitySystemGlobals.h"
7#include "GKLAttributeSet.h"
8#include "GKLCharacter.h"
9#include "GKLEffects.h"
10#include "GKLGameplayTags.h"
11#include "Misc/EngineVersionComparison.h"
12
13UGKLGameplayAbility::UGKLGameplayAbility()
14{
15 InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
16 NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted;
17 CostGameplayEffectClass = UGKLCostEffect::StaticClass();
18 CooldownGameplayEffectClass = UGKLCooldownEffect::StaticClass();
19 ActivationBlockedTags.AddTag(GKLTags::State_Dead);
20}
21
22UGameplayEffect* UGKLGameplayAbility::GetCostGameplayEffect() const
23{
24 return (StaminaCost > 0.f || ManaCost > 0.f) ? Super::GetCostGameplayEffect() : nullptr;
25}
26
27UGameplayEffect* UGKLGameplayAbility::GetCooldownGameplayEffect() const
28{
29 return CooldownDuration > 0.f ? Super::GetCooldownGameplayEffect() : nullptr;
30}
31
32const FGameplayTagContainer* UGKLGameplayAbility::GetCooldownTags() const
33{
34 TempCooldownTags.Reset();
35 if (const FGameplayTagContainer* EffectTags = Super::GetCooldownTags())
36 {
37 TempCooldownTags.AppendTags(*EffectTags);
38 }
39 if (CooldownDuration > 0.f)
40 {
41 TempCooldownTags.AppendTags(CooldownTags);
42 }
43 return &TempCooldownTags;
44}
45
46bool UGKLGameplayAbility::CheckCost(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
47 FGameplayTagContainer* OptionalRelevantTags) const
48{
49 if (!GetCostGameplayEffect())
50 {
51 return true;
52 }
53 const UAbilitySystemComponent* ASC = ActorInfo ? ActorInfo->AbilitySystemComponent.Get() : nullptr;
54 if (!ASC)
55 {
56 return false;
57 }
58
59 // The cost effect's magnitudes are SetByCaller, so the default check cannot evaluate them.
60 const bool bEnough =
61 ASC->GetNumericAttribute(UGKLAttributeSet::GetStaminaAttribute()) >= StaminaCost &&
62 ASC->GetNumericAttribute(UGKLAttributeSet::GetManaAttribute()) >= ManaCost;
63
64 if (!bEnough && OptionalRelevantTags)
65 {
66 OptionalRelevantTags->AddTag(UAbilitySystemGlobals::Get().ActivateFailCostTag);
67 }
68 return bEnough;
69}
70
71void UGKLGameplayAbility::ApplyCost(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
72 const FGameplayAbilityActivationInfo ActivationInfo) const
73{
74 const UGameplayEffect* CostEffect = GetCostGameplayEffect();
75 if (!CostEffect)
76 {
77 return;
78 }
79 const FGameplayEffectSpecHandle Spec = MakeOutgoingGameplayEffectSpec(Handle, ActorInfo, ActivationInfo, CostEffect->GetClass(), GetAbilityLevel(Handle, ActorInfo));
80 if (Spec.IsValid())
81 {
82 Spec.Data->SetSetByCallerMagnitude(GKLTags::Data_Cost_Stamina, -StaminaCost);
83 Spec.Data->SetSetByCallerMagnitude(GKLTags::Data_Cost_Mana, -ManaCost);
84 ApplyGameplayEffectSpecToOwner(Handle, ActorInfo, ActivationInfo, Spec);
85 }
86}
87
88void UGKLGameplayAbility::ApplyCooldown(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
89 const FGameplayAbilityActivationInfo ActivationInfo) const
90{
91 const UGameplayEffect* CooldownEffect = GetCooldownGameplayEffect();
92 if (!CooldownEffect)
93 {
94 return;
95 }
96 const FGameplayEffectSpecHandle Spec = MakeOutgoingGameplayEffectSpec(Handle, ActorInfo, ActivationInfo, CooldownEffect->GetClass(), GetAbilityLevel(Handle, ActorInfo));
97 if (Spec.IsValid())
98 {
99 Spec.Data->SetSetByCallerMagnitude(GKLTags::Data_Cooldown, CooldownDuration);
100 Spec.Data->DynamicGrantedTags.AppendTags(CooldownTags);
101 ApplyGameplayEffectSpecToOwner(Handle, ActorInfo, ActivationInfo, Spec);
102 }
103}
104
105AGKLCharacter* UGKLGameplayAbility::GetLiteCharacter() const
106{
107 return Cast<AGKLCharacter>(GetAvatarActorFromActorInfo());
108}
109
110void UGKLGameplayAbility::AddAbilityTag(const FGameplayTag& Tag)
111{
112#if UE_VERSION_NEWER_THAN(5, 4, 99)
113 FGameplayTagContainer Tags = GetAssetTags();
114 Tags.AddTag(Tag);
115 SetAssetTags(Tags);
116#else
117 AbilityTags.AddTag(Tag);
118#endif
119}

Still desyncing in packaged builds?

Free code fixes one symptom. A Diagnostic finds the cause across your project in two days.