Payback 0.0.1
CK Graduation Project
로딩중...
검색중...
일치하는것 없음
USituationBase 클래스 참조

#include <SituationBase.h>

USituationBase에 대한 상속 다이어그램 :
Inheritance graph
USituationBase에 대한 협력 다이어그램:
Collaboration graph

Public 멤버 함수

void Initialize (const FDT_SituationTable &InSituationData, const FSituationBuffData &InBuffData)
 
void StartTicking (UWorld *World)
 
void StopTicking (UWorld *World)
 
void ApplyBuff (APlayerController *TargetPC)
 
void RefreshForWeapon (const APlayerController *TargetPC)
 
void RemoveBuff (APlayerController *TargetPC)
 
float GetBuffRemainingTime (const APlayerController *TargetPC) const
 
float GetBuffDuration (const APlayerController *TargetPC) const
 
FText BuildBuffDescription (const APlayerController *TargetPC) const
 
FORCEINLINE const FDT_SituationTableGetSituationData () const
 
FORCEINLINE const FSituationBuffDataGetBuffData () const
 
UConstellationBaseGetConstellation () const
 
void SetConstellation (UConstellationBase *InConstellation)
 
FORCEINLINE FName GetSituationID () const
 
FORCEINLINE ESituationTag GetSituationTags () const
 
FORCEINLINE int32 GetSituationTagCount () const
 
FORCEINLINE bool IsBuffActive () const
 
FORCEINLINE UTexture2D * GetSituationIcon () const
 

Public 속성

FSimpleMulticastDelegate OnSituationTriggered
 
FSimpleMulticastDelegate OnBuffExpired
 

Protected 멤버 함수

void OnTriggered ()
 
void HandleIntervalElapsed ()
 
void HandleEffectRemoved (const FGameplayEffectRemovalInfo &RemovalInfo)
 
void ClearAppliedEffect (UAbilitySystemComponent *ASC)
 
void ApplyBuffEffect (UAbilitySystemComponent *ASC, float OverrideDuration)
 
void InjectWeaponMagnitudes (const UAbilitySystemComponent *ASC, const UClass *EffectClass, const FGameplayEffectSpecHandle &SpecHandle) const
 
void FillMagnitudeTokens (const APlayerController *TargetPC, FString &InOutText) const
 

정적 Protected 멤버 함수

static UAbilitySystemComponent * ResolveASC (const APlayerController *TargetPC)
 
static FGameplayTag ResolveCurrentWeaponTag (const UAbilitySystemComponent *ASC)
 
static bool ResolveModifierMagnitude (const FGameplayModifierInfo &Modifier, const FConstellationWeaponMagnitude *ActiveEntry, float &OutMagnitude, float SituationRank=1.0f)
 

Protected 속성

FDT_SituationTable SituationData
 
FSituationBuffData BuffData
 
TObjectPtr< UConstellationBaseConstellation
 
FActiveGameplayEffectHandle AppliedHandle
 

Private 속성

FTimerHandle IntervalTimerHandle
 

상세한 설명

플레이어가 장착한 "상황"(카드) 인스턴스.

카드가 버프를 소유한다. Buff_Master 의 Interval 마다 발동해 자신의 GE 를 플레이어에게 적용하고, 발동 사실을 알려 성좌들이 채팅으로 반응하게 한다.

멤버 함수 문서화

◆ ApplyBuff()

void USituationBase::ApplyBuff ( APlayerController *  TargetPC)
63{
64 if (BuffData.IsValid() == false)
65 {
66 LOG_WARNING(LogCKAbility, "상황 '%s'에 유효한 버프가 없어 적용을 건너뜁니다.", *SituationData.Situation_ID.ToString());
67 return;
68 }
69
70 UAbilitySystemComponent* ASC = ResolveASC(TargetPC);
71
72 if (ASC == nullptr)
73 {
74 LOG_WARNING(LogCKAbility, "ASC 를 찾을 수 없어 상황 버프 적용 중단");
75 return;
76 }
77
78 ApplyBuffEffect(ASC, 0.0f);
79}
#define LOG_WARNING(Category, Format,...)
Definition CK_UE.h:39
void ApplyBuffEffect(UAbilitySystemComponent *ASC, float OverrideDuration)
Definition SituationBase.cpp:113
FSituationBuffData BuffData
Definition SituationBase.h:157
FDT_SituationTable SituationData
Definition SituationBase.h:154
static UAbilitySystemComponent * ResolveASC(const APlayerController *TargetPC)
Definition SituationBase.cpp:511
FName Situation_ID
Definition DT_SituationTable.h:32
FORCEINLINE bool IsValid() const
Definition SituationBuffData.h:36
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ApplyBuffEffect()

void USituationBase::ApplyBuffEffect ( UAbilitySystemComponent *  ASC,
float  OverrideDuration 
)
protected
114{
115 UClass* EffectClass = BuffData.EffectClass.LoadSynchronous();
116
117 if (EffectClass == nullptr)
118 {
119 LOG_ERROR(LogCKAbility, "버프 '%s'의 GE 를 로드할 수 없습니다.", *BuffData.Buff_ID.ToString());
120 return;
121 }
122
123 // 같은 카드가 다음 주기에 또 발동하면 이전 GE 를 먼저 걷는다.
124 // 그냥 덮어쓰면 이전 핸들이 추적에서 빠진 채 살아남아, 그게 만료될 때
125 // HandleEffectRemoved 가 방금 붙인 새 핸들을 무효화해 버린다.
127
128 FGameplayEffectContextHandle Context = ASC->MakeEffectContext();
129 Context.AddSourceObject(this);
130
131 // 이 시점의 소유 태그가 스펙에 캡처되어 모디파이어의 TargetTags 조건 판정에 쓰인다.
132 const FGameplayEffectSpecHandle SpecHandle = ASC->MakeOutgoingSpec(EffectClass, SituationData.Situation_Rank, Context);
133
134 if (SpecHandle.IsValid() == false || SpecHandle.Data.IsValid() == false)
135 {
136 return;
137 }
138
139 InjectWeaponMagnitudes(ASC, EffectClass, SpecHandle);
140
141 // 무기를 바꿔 다시 붙일 때는 남은 시간만큼만 되살린다.
142 if (OverrideDuration > 0.0f)
143 {
144 SpecHandle.Data->SetDuration(OverrideDuration, true);
145 }
146
147 AppliedHandle = ASC->ApplyGameplayEffectSpecToSelf(*SpecHandle.Data.Get());
148
149 // Instant GE 는 Active 핸들이 남지 않는다. 이 경우 만료 통지 없이 곧바로 끝난 것으로 본다.
150 if (AppliedHandle.IsValid() == false)
151 {
152 return;
153 }
154
155 // 지속 시간은 GE 가 소유한다. 만료든 디스펠이든 제거 시점을 GE 로부터 통지받는다.
156 if (FOnActiveGameplayEffectRemoved_Info* RemovedDelegate = ASC->OnGameplayEffectRemoved_InfoDelegate(AppliedHandle))
157 {
158 RemovedDelegate->AddUObject(this, &USituationBase::HandleEffectRemoved);
159 }
160}
#define LOG_ERROR(Category, Format,...)
Definition CK_UE.h:40
void InjectWeaponMagnitudes(const UAbilitySystemComponent *ASC, const UClass *EffectClass, const FGameplayEffectSpecHandle &SpecHandle) const
Definition SituationBase.cpp:163
void HandleEffectRemoved(const FGameplayEffectRemovalInfo &RemovalInfo)
Definition SituationBase.cpp:285
void ClearAppliedEffect(UAbilitySystemComponent *ASC)
Definition SituationBase.cpp:425
FActiveGameplayEffectHandle AppliedHandle
Definition SituationBase.h:164
int32 Situation_Rank
Definition DT_SituationTable.h:55
TSoftClassPtr< UGameplayEffect > EffectClass
Definition SituationBuffData.h:33
FName Buff_ID
Definition SituationBuffData.h:20
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ BuildBuffDescription()

FText USituationBase::BuildBuffDescription ( const APlayerController *  TargetPC) const
391{
392 FString Result = SituationData.Description.ToString();
393
394 FillMagnitudeTokens(TargetPC, Result);
395
396 // 성좌 치환자는 이 카드에 묶인 성좌만 채울 수 있다.
397 if (Constellation == nullptr)
398 {
399 // 문구가 성좌를 부르는데 성좌가 없으면 치환자가 화면에 그대로 노출된다.
400 if (Result.Contains(TEXT("{{")))
401 {
402 LOG_WARNING(LogCKAbility, "상황 '%s'에 성좌가 묶여 있지 않아 성좌 치환자를 채우지 못했습니다. 남은 문구: %s",
403 *SituationData.Situation_ID.ToString(), *Result);
404 }
405
406 return FText::FromString(Result);
407 }
408
409 return Constellation->FormatReaction(FText::FromString(Result));
410}
void FillMagnitudeTokens(const APlayerController *TargetPC, FString &InOutText) const
Definition SituationBase.cpp:316
TObjectPtr< UConstellationBase > Constellation
Definition SituationBase.h:160
FText Description
Definition DT_SituationTable.h:39
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ ClearAppliedEffect()

void USituationBase::ClearAppliedEffect ( UAbilitySystemComponent *  ASC)
protected
426{
427 if (AppliedHandle.IsValid() == false)
428 {
429 return;
430 }
431
432 // 의도적인 제거를 만료로 오해하지 않도록 먼저 구독을 끊는다.
433 if (FOnActiveGameplayEffectRemoved_Info* RemovedDelegate = ASC->OnGameplayEffectRemoved_InfoDelegate(AppliedHandle))
434 {
435 RemovedDelegate->RemoveAll(this);
436 }
437
438 ASC->RemoveActiveGameplayEffect(AppliedHandle);
439 AppliedHandle.Invalidate();
440}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ FillMagnitudeTokens()

void USituationBase::FillMagnitudeTokens ( const APlayerController *  TargetPC,
FString &  InOutText 
) const
protected
317{
318 const UClass* EffectClass = BuffData.EffectClass.LoadSynchronous();
319
320 if (EffectClass == nullptr)
321 {
322 LOG_WARNING(LogCKAbility, "상황 '%s'의 버프 '%s' GE 를 로드하지 못해 수치 치환자를 채울 수 없습니다. Buff_Master 의 GE_Path 를 확인하세요.",
323 *SituationData.Situation_ID.ToString(), *BuffData.Buff_ID.ToString());
324 return;
325 }
326
327 const UAbilitySystemComponent* ASC = ResolveASC(TargetPC);
328
329 if (ASC == nullptr)
330 {
331 LOG_WARNING(LogCKAbility, "상황 '%s': ASC 를 찾지 못해 수치 치환자를 채울 수 없습니다.", *SituationData.Situation_ID.ToString());
332 return;
333 }
334
335 const UGE_ConstellationBuffBase* EffectCDO = Cast<UGE_ConstellationBuffBase>(EffectClass->GetDefaultObject());
336
337 if (EffectCDO == nullptr)
338 {
339 LOG_WARNING(LogCKAbility, "상황 '%s'의 GE(%s)가 %s 파생이 아니라 수치 치환자를 채울 수 없습니다. GE 의 부모 클래스를 바꿔야 합니다.",
340 *SituationData.Situation_ID.ToString(), *EffectClass->GetName(), NAMEOF(UGE_ConstellationBuffBase));
341 return;
342 }
343
344 // 무기별로 다른 모디파이어가 한 GE 에 섞여 있어, 지금 장착한 무기 항목만 골라낸다.
345 const FConstellationWeaponMagnitude* ActiveEntry = EffectCDO->WeaponMagnitudes.Find(ResolveCurrentWeaponTag(ASC));
346
347 int32 SlotIndex = 1;
348
349 for (const FGameplayModifierInfo& Modifier : EffectCDO->Modifiers)
350 {
351 float Magnitude = 0.0f;
352
353 if (ResolveModifierMagnitude(Modifier, ActiveEntry, Magnitude, SituationData.Situation_Rank) == false)
354 {
355 continue;
356 }
357
358 const FProperty* AttributeProperty = Modifier.Attribute.GetUProperty();
359
360 // 어트리뷰트에 DisplayName 메타를 붙여 두면 그 이름이, 없으면 어트리뷰트명이 나온다.
361 FString AttributeName;
362 if (AttributeProperty)
363 {
364#if WITH_METADATA
365 AttributeName = AttributeProperty->GetMetaData(TEXT("DisplayName"));
366#endif
367
368 if (AttributeName.IsEmpty())
369 {
370 AttributeName = FName::NameToDisplayString(AttributeProperty->GetAuthoredName(), false);
371 }
372 }
373 else
374 {
375 AttributeName = Modifier.Attribute.GetName();
376 }
377
378 // "증가 / 하락" 방향은 기획 문구가 이미 담고 있어 크기만 넣는다.
379 const FString ValueText = FString::Printf(TEXT("%.4g"), FMath::Abs(Magnitude));
380
381 // 표에 박힌 조사는 값의 받침에 맞춰 ReplaceToken 이 함께 고친다.
382 KoreanText::ReplaceToken(InOutText, FString::Printf(TEXT("{{name%d}}"), SlotIndex), AttributeName);
383 KoreanText::ReplaceToken(InOutText, FString::Printf(TEXT("{{value%d}}"), SlotIndex), ValueText);
384
385 ++SlotIndex;
386 }
387}
#define NAMEOF(Type)
Definition CK_UE.h:30
Definition GE_ConstellationBuffBase.h:47
TMap< FGameplayTag, FConstellationWeaponMagnitude > WeaponMagnitudes
Definition GE_ConstellationBuffBase.h:56
static FGameplayTag ResolveCurrentWeaponTag(const UAbilitySystemComponent *ASC)
Definition SituationBase.cpp:273
static bool ResolveModifierMagnitude(const FGameplayModifierInfo &Modifier, const FConstellationWeaponMagnitude *ActiveEntry, float &OutMagnitude, float SituationRank=1.0f)
Definition SituationBase.cpp:293
CK_UE_API void ReplaceToken(FString &InOutText, const FString &Token, const FString &Value)
Definition KoreanText.cpp:133
Definition GE_ConstellationBuffBase.h:16
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetBuffData()

FORCEINLINE const FSituationBuffData & USituationBase::GetBuffData ( ) const
inline
73 {
74 return BuffData;
75 }

◆ GetBuffDuration()

float USituationBase::GetBuffDuration ( const APlayerController *  TargetPC) const
470{
471 if (AppliedHandle.IsValid() == false)
472 {
473 return -1.0f;
474 }
475
476 const UAbilitySystemComponent* ASC = ResolveASC(TargetPC);
477
478 if (ASC == nullptr)
479 {
480 return -1.0f;
481 }
482
483 const FActiveGameplayEffect* ActiveEffect = ASC->GetActiveGameplayEffect(AppliedHandle);
484
485 if (ActiveEffect == nullptr)
486 {
487 return -1.0f;
488 }
489
490 // 영구(Infinite) GE 는 INFINITE_DURATION(-1) 이 들어 있다.
491 return ActiveEffect->GetDuration();
492}
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ GetBuffRemainingTime()

float USituationBase::GetBuffRemainingTime ( const APlayerController *  TargetPC) const
444{
445 if (AppliedHandle.IsValid() == false)
446 {
447 return -1.0f;
448 }
449
450 UAbilitySystemComponent* ASC = ResolveASC(TargetPC);
451
452 if (ASC == nullptr)
453 {
454 return -1.0f;
455 }
456
457 const FActiveGameplayEffect* ActiveEffect = ASC->GetActiveGameplayEffect(AppliedHandle);
458
459 if (ActiveEffect == nullptr)
460 {
461 return -1.0f;
462 }
463
464 // 영구(Infinite) GE 면 GetTimeRemaining 이 -1 을 돌려준다.
465 return ActiveEffect->GetTimeRemaining(ASC->GetWorld()->GetTimeSeconds());
466}
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetConstellation()

UConstellationBase * USituationBase::GetConstellation ( ) const
414{
415 return Constellation;
416}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetSituationData()

FORCEINLINE const FDT_SituationTable & USituationBase::GetSituationData ( ) const
inline
68 {
69 return SituationData;
70 }
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetSituationIcon()

FORCEINLINE UTexture2D * USituationBase::GetSituationIcon ( ) const
inline
105 {
106 //태그가 하나만 달려있다면 그 태그에 대응되는 아이콘을 가져옴. 하지만 여러개라면 'Complex'라는 유형의 아이콘을 가져오게 구현.
107 const FName Path = FName(GetSituationTagCount() > 1 ? "Complex" : Utils::EnumToString(GetSituationTags()));
108 UTexture2D* IconTextureLocal = GetEnvironmentAssetByKey<UTexture2D>(Path);
109 return IconTextureLocal;
110 }
FORCEINLINE ESituationTag GetSituationTags() const
Definition SituationBase.h:87
FORCEINLINE int32 GetSituationTagCount() const
Definition SituationBase.h:92
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetSituationID()

FORCEINLINE FName USituationBase::GetSituationID ( ) const
inline
83 {
85 }
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetSituationTagCount()

FORCEINLINE int32 USituationBase::GetSituationTagCount ( ) const
inline
93 {
94 int32 Result = 0, Value = static_cast<int32>(GetSituationTags());
95 while (Value) ++Result, Value &= (Value - 1); //While문임.
96 return Result;
97 }

◆ GetSituationTags()

FORCEINLINE ESituationTag USituationBase::GetSituationTags ( ) const
inline
88 {
90 }
ESituationTag ParsedTags
Definition DT_SituationTable.h:67
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ HandleEffectRemoved()

void USituationBase::HandleEffectRemoved ( const FGameplayEffectRemovalInfo &  RemovalInfo)
protected
286{
287 AppliedHandle.Invalidate();
288
289 OnBuffExpired.Broadcast();
290}
FSimpleMulticastDelegate OnBuffExpired
Definition SituationBase.h:124
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ HandleIntervalElapsed()

void USituationBase::HandleIntervalElapsed ( )
protected
56{
57 OnSituationTriggered.Broadcast();
59}
FSimpleMulticastDelegate OnSituationTriggered
Definition SituationBase.h:121
void OnTriggered()
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ Initialize()

void USituationBase::Initialize ( const FDT_SituationTable InSituationData,
const FSituationBuffData InBuffData 
)
22{
23 SituationData = InSituationData;
24 BuffData = InBuffData;
25}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ InjectWeaponMagnitudes()

void USituationBase::InjectWeaponMagnitudes ( const UAbilitySystemComponent *  ASC,
const UClass *  EffectClass,
const FGameplayEffectSpecHandle &  SpecHandle 
) const
protected
164{
165 const UGE_ConstellationBuffBase* EffectCDO = Cast<UGE_ConstellationBuffBase>(EffectClass->GetDefaultObject());
166
167 if (EffectCDO == nullptr)
168 {
169 LOG_WARNING(LogCKAbility, "버프 '%s'의 GE(%s)가 %s 파생이 아니라 무기별 수치를 넣을 수 없습니다. SetByCaller 모디파이어는 0 으로 적용됩니다.",
170 *BuffData.Buff_ID.ToString(), *EffectClass->GetName(), NAMEOF(UGE_ConstellationBuffBase));
171 return;
172 }
173
174 if (EffectCDO->WeaponMagnitudes.IsEmpty())
175 {
176 // 모디파이어가 ScalableFloat 이면 비워두는 게 정상이다.
177 // 반면 SetByCaller 인데 비어 있으면 값을 아무도 안 채워 GAS 가 0 으로 적용한다.
178 auto UsesSetByCaller = [](const FGameplayModifierInfo& Modifier)
179 {
180 return Modifier.ModifierMagnitude.GetMagnitudeCalculationType() == EGameplayEffectMagnitudeCalculation::SetByCaller;
181 };
182
183 if (EffectCDO->Modifiers.ContainsByPredicate(UsesSetByCaller))
184 {
185 LOG_WARNING(LogCKAbility, "버프 '%s'의 GE(%s)는 SetByCaller 모디파이어를 쓰는데 WeaponMagnitudes 가 비어 있습니다. 수치가 0 으로 적용됩니다.",
186 *BuffData.Buff_ID.ToString(), *EffectClass->GetName());
187 }
188
189 return;
190 }
191
192 const FGameplayTag CurrentWeaponTag = ResolveCurrentWeaponTag(ASC);
193 const FConstellationWeaponMagnitude* ActiveEntry = EffectCDO->WeaponMagnitudes.Find(CurrentWeaponTag);
194
195 // 키가 정확히 일치해야 찾는다. 장착 태그가 Weapon.Sword.Equipped 인데 키가 Weapon.Sword 면 못 찾는다.
196 if (ActiveEntry == nullptr)
197 {
198 TArray<FGameplayTag> RegisteredWeaponTags;
199 EffectCDO->WeaponMagnitudes.GetKeys(RegisteredWeaponTags);
200
201 FString RegisteredTagNames;
202
203 for (const FGameplayTag& WeaponTag : RegisteredWeaponTags)
204 {
205 RegisteredTagNames += (RegisteredTagNames.IsEmpty() ? TEXT("") : TEXT(", ")) + WeaponTag.ToString();
206 }
207
208 LOG_WARNING(LogCKAbility, "버프 '%s': 현재 무기 태그 '%s' 가 WeaponMagnitudes 키에 없어 모든 모디파이어가 무력화됩니다. 등록된 키: [%s]",
209 *BuffData.Buff_ID.ToString(),
210 CurrentWeaponTag.IsValid() ? *CurrentWeaponTag.ToString() : TEXT("(없음)"),
211 *RegisteredTagNames);
212 }
213
214 bool bAppliedAnyMagnitude = false;
215
216 // 맵이 아니라 모디파이어를 기준으로 돈다.
217 // SetByCaller 값을 하나라도 빠뜨리면 GAS 가 0 으로 처리하는데,
218 // 곱연산 모디파이어에 0 이 들어가면 어트리뷰트 자체가 0 이 되어버린다.
219 for (const FGameplayModifierInfo& Modifier : EffectCDO->Modifiers)
220 {
221 if (Modifier.ModifierMagnitude.GetMagnitudeCalculationType() != EGameplayEffectMagnitudeCalculation::SetByCaller)
222 {
223 continue;
224 }
225
226 const FGameplayTag MagnitudeTag = Modifier.ModifierMagnitude.GetSetByCallerFloat().DataTag;
227
228 if (MagnitudeTag.IsValid() == false)
229 {
230 continue;
231 }
232
233 // 장착 무기가 이 모디파이어를 지목했으면 실제 수치를 넣는다.
234 if (ActiveEntry && ActiveEntry->MagnitudeTag == MagnitudeTag)
235 {
236 SpecHandle.Data->SetSetByCallerMagnitude(MagnitudeTag, ActiveEntry->Magnitude);
237 bAppliedAnyMagnitude = true;
238 continue;
239 }
240
241 // 그 외에는 연산별 항등값으로 무력화한다. Add 계열은 0, 곱/나눗셈 계열은 1.
242 switch (Modifier.ModifierOp.GetValue())
243 {
244 case EGameplayModOp::AddBase:
245 case EGameplayModOp::AddFinal:
246 SpecHandle.Data->SetSetByCallerMagnitude(MagnitudeTag, 0.0f);
247 break;
248
249 case EGameplayModOp::MultiplyAdditive:
250 case EGameplayModOp::MultiplyCompound:
251 case EGameplayModOp::DivideAdditive:
252 SpecHandle.Data->SetSetByCallerMagnitude(MagnitudeTag, 1.0f);
253 break;
254
255 default:
256 // Override 는 무력화할 항등값이 없다. 값을 안 넣으면 0 으로 덮어써지므로 경고만 남긴다.
257 LOG_WARNING(LogCKAbility, "버프 '%s'의 모디파이어가 Override 라 무기별 분기를 적용할 수 없습니다.", *BuffData.Buff_ID.ToString());
258 break;
259 }
260 }
261
262 // 무기 항목은 찾았는데 어느 모디파이어도 지목하지 못한 경우.
263 if (ActiveEntry && bAppliedAnyMagnitude == false)
264 {
265 LOG_WARNING(LogCKAbility, "버프 '%s': 무기 '%s' 의 MagnitudeTag('%s')와 일치하는 SetByCaller 모디파이어가 GE 에 없습니다.",
266 *BuffData.Buff_ID.ToString(),
267 *CurrentWeaponTag.ToString(),
268 ActiveEntry->MagnitudeTag.IsValid() ? *ActiveEntry->MagnitudeTag.ToString() : TEXT("(없음)"));
269 }
270}
float Magnitude
Definition GE_ConstellationBuffBase.h:27
FGameplayTag MagnitudeTag
Definition GE_ConstellationBuffBase.h:24
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ IsBuffActive()

FORCEINLINE bool USituationBase::IsBuffActive ( ) const
inline
100 {
101 return AppliedHandle.IsValid();
102 }

◆ OnTriggered()

void USituationBase::OnTriggered ( )
protected
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ RefreshForWeapon()

void USituationBase::RefreshForWeapon ( const APlayerController *  TargetPC)
83{
84 if (AppliedHandle.IsValid() == false)
85 {
86 return;
87 }
88
89 UAbilitySystemComponent* ASC = ResolveASC(TargetPC);
90
91 if (ASC == nullptr)
92 {
93 return;
94 }
95
96 // 남은 시간을 먼저 읽어둔다. 영구 GE 면 -1 이 나온다.
97 const float Remaining = GetBuffRemainingTime(TargetPC);
98
99 // 곧 만료될 버프는 되살리지 않는다. 만료 통지는 GE 가 알아서 보낸다.
100 if (Remaining >= 0.0f && FMath::IsNearlyZero(Remaining))
101 {
102 return;
103 }
104
106
107 // 새 무기 태그가 캡처되도록 스펙을 다시 만들어 적용한다.
108 // 영구 GE(-1)는 원래 지속 정책을 그대로 쓰고, 일시 GE 는 남은 시간만큼만 되살린다.
109 ApplyBuffEffect(ASC, Remaining < 0.0f ? 0.0f : Remaining);
110}
float GetBuffRemainingTime(const APlayerController *TargetPC) const
Definition SituationBase.cpp:443
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ RemoveBuff()

void USituationBase::RemoveBuff ( APlayerController *  TargetPC)
496{
497 if (AppliedHandle.IsValid() == false)
498 {
499 return;
500 }
501
502 if (UAbilitySystemComponent* ASC = ResolveASC(TargetPC))
503 {
504 ASC->RemoveActiveGameplayEffect(AppliedHandle);
505 }
506
507 AppliedHandle.Invalidate();
508}
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ ResolveASC()

UAbilitySystemComponent * USituationBase::ResolveASC ( const APlayerController *  TargetPC)
staticprotected
512{
513 if (TargetPC == nullptr)
514 {
515 return nullptr;
516 }
517
518 // ASC 소유자가 Pawn 인지 PlayerState 인지에 관계없이 인터페이스로 해석한다.
519 if (const IAbilitySystemInterface* PawnInterface = Cast<IAbilitySystemInterface>(TargetPC->GetPawn()))
520 {
521 return PawnInterface->GetAbilitySystemComponent();
522 }
523
524 if (const IAbilitySystemInterface* StateInterface = Cast<IAbilitySystemInterface>(TargetPC->PlayerState))
525 {
526 return StateInterface->GetAbilitySystemComponent();
527 }
528
529 return nullptr;
530}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ResolveCurrentWeaponTag()

FGameplayTag USituationBase::ResolveCurrentWeaponTag ( const UAbilitySystemComponent *  ASC)
staticprotected
274{
275 static const FGameplayTag WeaponRootTag = FGameplayTag::RequestGameplayTag(TEXT("Weapon"), false);
276
277 FGameplayTagContainer OwnedTags;
278 ASC->GetOwnedGameplayTags(OwnedTags);
279
280 // 무기 태그는 장착 시 WeaponLoadoutComponent 가 하나만 올려둔다.
281 return OwnedTags.Filter(FGameplayTagContainer(WeaponRootTag)).First();
282}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ResolveModifierMagnitude()

bool USituationBase::ResolveModifierMagnitude ( const FGameplayModifierInfo &  Modifier,
const FConstellationWeaponMagnitude ActiveEntry,
float &  OutMagnitude,
float  SituationRank = 1.0f 
)
staticprotected
294{
295 OutMagnitude = 0.0f;
296
297 // SetByCaller 가 아니면 GE 에 저작된 크기를 그대로 쓴다.
298 // 커스텀 계산식처럼 정적으로 못 읽는 것은 미리 보여줄 수 없다.
299 if (Modifier.ModifierMagnitude.GetMagnitudeCalculationType() != EGameplayEffectMagnitudeCalculation::SetByCaller)
300 {
301 return Modifier.ModifierMagnitude.GetStaticMagnitudeIfPossible(SituationRank, OutMagnitude);
302 }
303
304 // SetByCaller 는 장착 무기가 지목한 하나만 실제 수치를 받고
305 // 나머지는 항등값으로 무력화된다. InjectWeaponMagnitudes 와 같은 기준이어야 한다.
306 if (ActiveEntry == nullptr || ActiveEntry->MagnitudeTag != Modifier.ModifierMagnitude.GetSetByCallerFloat().DataTag)
307 {
308 return false;
309 }
310
311 OutMagnitude = ActiveEntry->Magnitude;
312 return true;
313}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ SetConstellation()

void USituationBase::SetConstellation ( UConstellationBase InConstellation)
420{
421 Constellation = InConstellation;
422}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ StartTicking()

void USituationBase::StartTicking ( UWorld *  World)
29{
30 if (World == nullptr)
31 {
32 return;
33 }
34
35 if (BuffData.Interval <= 0.0f)
36 {
37 LOG_WARNING(LogCK, "상황 '%s'의 버프 '%s' Interval 이 0 이하라 발동하지 않습니다.", *SituationData.Situation_ID.ToString(), *BuffData.Buff_ID.ToString());
38 return;
39 }
40
41 // 반복 타이머라 한 번만 걸어두면 계속 돈다.
42 World->GetTimerManager().SetTimer(IntervalTimerHandle, this, &USituationBase::HandleIntervalElapsed, BuffData.Interval, true);
43}
void HandleIntervalElapsed()
Definition SituationBase.cpp:55
FTimerHandle IntervalTimerHandle
Definition SituationBase.h:167
float Interval
Definition SituationBuffData.h:24
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ StopTicking()

void USituationBase::StopTicking ( UWorld *  World)
47{
48 if (World)
49 {
50 World->GetTimerManager().ClearTimer(IntervalTimerHandle);
51 }
52}

멤버 데이터 문서화

◆ AppliedHandle

FActiveGameplayEffectHandle USituationBase::AppliedHandle
protected

◆ BuffData

FSituationBuffData USituationBase::BuffData
protected

◆ Constellation

TObjectPtr<UConstellationBase> USituationBase::Constellation
protected

◆ IntervalTimerHandle

FTimerHandle USituationBase::IntervalTimerHandle
private

◆ OnBuffExpired

FSimpleMulticastDelegate USituationBase::OnBuffExpired

◆ OnSituationTriggered

FSimpleMulticastDelegate USituationBase::OnSituationTriggered

◆ SituationData

FDT_SituationTable USituationBase::SituationData
protected

이 클래스에 대한 문서화 페이지는 다음의 파일들로부터 생성되었습니다.: