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

#include <EnemyCombatSubsystem.h>

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

Public 멤버 함수

virtual void Deinitialize () override
 
bool RequestAttackToken (AActor *TargetActor, AActor *Requester)
 
void ReleaseAttackToken (AActor *Requester)
 
void UnregisterAttackTokenActor (AActor *Requester)
 

Private 멤버 함수

bool HasAttackToken (const AActor *Requester) const
 
bool RemoveAttackTokenHolder (AActor *Requester)
 
void CompactTokenData (float CurrentTime)
 
FEnemyAttackTokenCandidateFindOrAddCandidate (AActor *TargetActor, AActor *Requester, float CurrentTime)
 
FEnemyAttackTokenHistoryFindOrAddHistory (AActor *Requester)
 
const FEnemyAttackTokenHistoryFindHistory (const AActor *Requester) const
 
void TryGrantAttackTokens (float CurrentTime)
 
float CalculateCandidateScore (const FEnemyAttackTokenCandidate &Candidate, float CurrentTime) const
 
void RefreshDebugTimer ()
 
bool HasDebugTokenData () const
 
void DrawCombatTokenDebug ()
 
void DrawTokenDebugString (AActor *TargetActor, const FString &Text, const FColor &Color) const
 

Private 속성

TArray< TWeakObjectPtr< AActor > > TokenHolders
 
TArray< FEnemyAttackTokenCandidateTokenCandidates
 
TArray< FEnemyAttackTokenHistoryTokenHistories
 
FTimerHandle DebugTimerHandle
 

멤버 함수 문서화

◆ CalculateCandidateScore()

float UEnemyCombatSubsystem::CalculateCandidateScore ( const FEnemyAttackTokenCandidate Candidate,
float  CurrentTime 
) const
private
253{
254 const UEnemyCombatSettings* EnemyCombatSettings = GetDefault<UEnemyCombatSettings>();
255
256 AActor* Requester = Candidate.Requester.Get();
257 AActor* TargetActor = Candidate.TargetActor.Get();
258
259 if (IsValid(Requester) == false || IsValid(TargetActor) == false)
260 {
261 return -FLT_MAX;
262 }
263
264 float Score = 0.0f;
265
266 // 더 오래 기다릴수록 점수가 커짐.
267 const float WaitTime = CurrentTime - Candidate.FirstRequestTime;
268 Score += WaitTime * EnemyCombatSettings->GetWaitScore();
269
270 // 최근에 공격을 해서 패널티를 받은 액터는 기존 점수에서 패널티 점수 차감.
271 if (const FEnemyAttackTokenHistory* History = FindHistory(Requester))
272 {
273 const float TimeAfterRelease = CurrentTime - History->LastReleaseTime;
274 if (TimeAfterRelease < EnemyCombatSettings->GetRecentAttackPenaltyTime())
275 {
276 Score -= EnemyCombatSettings->GetRecentAttackPenaltyScore();
277 }
278 }
279
280 return Score;
281}
Definition EnemyCombatSettings.h:9
FORCEINLINE float GetWaitScore() const
Definition EnemyCombatSettings.h:33
FORCEINLINE float GetRecentAttackPenaltyScore() const
Definition EnemyCombatSettings.h:38
const FEnemyAttackTokenHistory * FindHistory(const AActor *Requester) const
Definition EnemyCombatSubsystem.cpp:203
TWeakObjectPtr< AActor > Requester
Definition EnemyCombatSubsystem.h:15
float FirstRequestTime
Definition EnemyCombatSubsystem.h:21
TWeakObjectPtr< AActor > TargetActor
Definition EnemyCombatSubsystem.h:18
Definition EnemyCombatSubsystem.h:29
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ CompactTokenData()

void UEnemyCombatSubsystem::CompactTokenData ( float  CurrentTime)
private
140{
141 const UEnemyCombatSettings* EnemyCombatSettings = GetDefault<UEnemyCombatSettings>();
142 const float CandidateExpireTime = EnemyCombatSettings->GetAttackTokenCandidateExpireTime();
143 const float RecentAttackPenaltyTime = EnemyCombatSettings->GetRecentAttackPenaltyTime();
144
145 // 유효하지 않는 액터 제거
146 TokenHolders.RemoveAll([](const TWeakObjectPtr<AActor>& TokenHolder)
147 {
148 return TokenHolder.IsValid() == false;
149 });
150
151 // 공격 후보자들이 요청한지 후보자초과 시간이 지났을 경우 제거
152 TokenCandidates.RemoveAll([CurrentTime, CandidateExpireTime](const FEnemyAttackTokenCandidate& Candidate)
153 {
154 return Candidate.Requester.IsValid() == false
155 || Candidate.TargetActor.IsValid() == false
156 || CurrentTime - Candidate.LastRequestTime > CandidateExpireTime;
157 });
158
159 // 공격 후 패넡티 시간이 지났을 경우 제거
160 TokenHistories.RemoveAll([CurrentTime, RecentAttackPenaltyTime](const FEnemyAttackTokenHistory& History)
161 {
162 return History.Requester.IsValid() == false
163 || CurrentTime - History.LastReleaseTime >= RecentAttackPenaltyTime;
164 });
165}
FORCEINLINE float GetRecentAttackPenaltyTime() const
Definition EnemyCombatSettings.h:28
FORCEINLINE float GetAttackTokenCandidateExpireTime() const
Definition EnemyCombatSettings.h:23
TArray< FEnemyAttackTokenCandidate > TokenCandidates
Definition EnemyCombatSubsystem.h:77
TArray< TWeakObjectPtr< AActor > > TokenHolders
Definition EnemyCombatSubsystem.h:74
TArray< FEnemyAttackTokenHistory > TokenHistories
Definition EnemyCombatSubsystem.h:80
Definition EnemyCombatSubsystem.h:11
float LastRequestTime
Definition EnemyCombatSubsystem.h:24
TWeakObjectPtr< AActor > Requester
Definition EnemyCombatSubsystem.h:33
float LastReleaseTime
Definition EnemyCombatSubsystem.h:36
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ Deinitialize()

void UEnemyCombatSubsystem::Deinitialize ( )
overridevirtual
9{
10 if (UWorld* World = GetWorld())
11 {
12 World->GetTimerManager().ClearTimer(DebugTimerHandle);
13 }
14
15 TokenHolders.Empty();
16 TokenCandidates.Empty();
17 TokenHistories.Empty();
18
19 Super::Deinitialize();
20}
FTimerHandle DebugTimerHandle
Definition EnemyCombatSubsystem.h:82

◆ DrawCombatTokenDebug()

void UEnemyCombatSubsystem::DrawCombatTokenDebug ( )
private
329{
330#if ENABLE_DRAW_DEBUG
331 const UEnemyCombatSettings* EnemyCombatSettings = GetDefault<UEnemyCombatSettings>();
332
333 const float CurrentTime = GetWorld()->GetTimeSeconds();
334 CompactTokenData(CurrentTime);
335
336 for (const TWeakObjectPtr<AActor>& TokenHolder : TokenHolders)
337 {
338 if (AActor* Holder = TokenHolder.Get())
339 {
340 DrawTokenDebugString(Holder, TEXT("Holder"), FColor::Red);
341 }
342 }
343
344 for (const FEnemyAttackTokenCandidate& Candidate : TokenCandidates)
345 {
346 AActor* Requester = Candidate.Requester.Get();
347 if (IsValid(Requester) == false)
348 {
349 continue;
350 }
351
352 const float Score = CalculateCandidateScore(Candidate, CurrentTime);
353 FString Text = FString::Printf(TEXT("Candidate\nScore: %.2f"), Score);
354
355 if (const FEnemyAttackTokenHistory* History = FindHistory(Requester))
356 {
357 const float PenaltyRemainTime = EnemyCombatSettings->GetRecentAttackPenaltyTime() - (CurrentTime - History->LastReleaseTime);
358 if (PenaltyRemainTime > 0.0f)
359 {
360 Text += FString::Printf(TEXT("\nPenalty: %.2f"), PenaltyRemainTime);
361 }
362 }
363
364 DrawTokenDebugString(Requester, Text, FColor::Yellow);
365 }
366
367 for (const FEnemyAttackTokenHistory& History : TokenHistories)
368 {
369 AActor* Requester = History.Requester.Get();
370 if (IsValid(Requester) == false || HasAttackToken(Requester))
371 {
372 continue;
373 }
374
375 const bool bIsCandidate = TokenCandidates.ContainsByPredicate([Requester](const FEnemyAttackTokenCandidate& Candidate)
376 {
377 return Candidate.Requester.Get() == Requester;
378 });
379
380 if (bIsCandidate)
381 {
382 continue;
383 }
384
385 const float PenaltyRemainTime = EnemyCombatSettings->GetRecentAttackPenaltyTime() - (CurrentTime - History.LastReleaseTime);
386 if (PenaltyRemainTime <= 0.0f)
387 {
388 continue;
389 }
390
391 const FString Text = FString::Printf(TEXT("Penalty\n%.2f"), PenaltyRemainTime);
392 DrawTokenDebugString(Requester, Text, FColor::Cyan);
393 }
394
396#endif
397}
void RefreshDebugTimer()
Definition EnemyCombatSubsystem.cpp:286
bool HasAttackToken(const AActor *Requester) const
Definition EnemyCombatSubsystem.cpp:46
void CompactTokenData(float CurrentTime)
Definition EnemyCombatSubsystem.cpp:139
void DrawTokenDebugString(AActor *TargetActor, const FString &Text, const FColor &Color) const
Definition EnemyCombatSubsystem.cpp:399
float CalculateCandidateScore(const FEnemyAttackTokenCandidate &Candidate, float CurrentTime) const
Definition EnemyCombatSubsystem.cpp:252
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ DrawTokenDebugString()

void UEnemyCombatSubsystem::DrawTokenDebugString ( AActor *  TargetActor,
const FString &  Text,
const FColor &  Color 
) const
private
400{
401#if ENABLE_DRAW_DEBUG
402 if (IsValid(TargetActor) == false)
403 {
404 return;
405 }
406
407 const FVector DrawLocation = TargetActor->GetActorLocation() + FVector(0.0f, 0.0f, 200.0f);
408 const float DrawDuration = GetDefault<UEnemyCombatSettings>()->GetCombatTokenDebugDrawInterval() * 1.1f; // 디버깅 텍스트 여유 시간
409 DrawDebugString(GetWorld(), DrawLocation, Text, nullptr, Color, DrawDuration, true, 1.0f);
410#endif
411}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ FindHistory()

const FEnemyAttackTokenHistory * UEnemyCombatSubsystem::FindHistory ( const AActor *  Requester) const
private
204{
205 for (const FEnemyAttackTokenHistory& History : TokenHistories)
206 {
207 if (History.Requester.Get() == Requester)
208 {
209 return &History;
210 }
211 }
212
213 return nullptr;
214}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ FindOrAddCandidate()

FEnemyAttackTokenCandidate & UEnemyCombatSubsystem::FindOrAddCandidate ( AActor *  TargetActor,
AActor *  Requester,
float  CurrentTime 
)
private
168{
170 {
171 if (Candidate.Requester.Get() == Requester)
172 {
173 Candidate.TargetActor = TargetActor;
174 Candidate.LastRequestTime = CurrentTime;
175 return Candidate;
176 }
177 }
178
179 FEnemyAttackTokenCandidate& NewCandidate = TokenCandidates.AddDefaulted_GetRef();
180 NewCandidate.Requester = Requester;
181 NewCandidate.TargetActor = TargetActor;
182 NewCandidate.FirstRequestTime = CurrentTime;
183 NewCandidate.LastRequestTime = CurrentTime;
184
185 return NewCandidate;
186}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ FindOrAddHistory()

FEnemyAttackTokenHistory & UEnemyCombatSubsystem::FindOrAddHistory ( AActor *  Requester)
private
189{
191 {
192 if (History.Requester.Get() == Requester)
193 {
194 return History;
195 }
196 }
197
198 FEnemyAttackTokenHistory& NewHistory = TokenHistories.AddDefaulted_GetRef();
199 NewHistory.Requester = Requester;
200 return NewHistory;
201}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ HasAttackToken()

bool UEnemyCombatSubsystem::HasAttackToken ( const AActor *  Requester) const
private
47{
48 if (IsValid(Requester) == false)
49 {
50 return false;
51 }
52
53 for (const TWeakObjectPtr<AActor>& TokenHolder : TokenHolders)
54 {
55 if (TokenHolder.Get() == Requester)
56 {
57 return true;
58 }
59 }
60
61 return false;
62}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ HasDebugTokenData()

bool UEnemyCombatSubsystem::HasDebugTokenData ( ) const
private
318{
319#if ENABLE_DRAW_DEBUG
320 return TokenHolders.IsEmpty() == false
321 || TokenCandidates.IsEmpty() == false
322 || TokenHistories.IsEmpty() == false;
323#else
324 return false;
325#endif
326}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ RefreshDebugTimer()

void UEnemyCombatSubsystem::RefreshDebugTimer ( )
private
287{
288#if ENABLE_DRAW_DEBUG
289 UWorld* World = GetWorld();
290 if (IsValid(World) == false)
291 {
292 return;
293 }
294
295 const UEnemyCombatSettings* EnemyCombatSettings = GetDefault<UEnemyCombatSettings>();
296 if (EnemyCombatSettings->ShouldShowCombatTokenDebug() == false || HasDebugTokenData() == false)
297 {
298 World->GetTimerManager().ClearTimer(DebugTimerHandle);
299 return;
300 }
301
302 if (World->GetTimerManager().IsTimerActive(DebugTimerHandle))
303 {
304 return;
305 }
306
307 World->GetTimerManager().SetTimer(
309 this,
311 EnemyCombatSettings->GetCombatTokenDebugDrawInterval(),
312 true
313 );
314#endif
315}
FORCEINLINE float GetCombatTokenDebugDrawInterval() const
Definition EnemyCombatSettings.h:48
FORCEINLINE bool ShouldShowCombatTokenDebug() const
Definition EnemyCombatSettings.h:43
bool HasDebugTokenData() const
Definition EnemyCombatSubsystem.cpp:317
void DrawCombatTokenDebug()
Definition EnemyCombatSubsystem.cpp:328
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ReleaseAttackToken()

void UEnemyCombatSubsystem::ReleaseAttackToken ( AActor *  Requester)
65{
66 if (IsValid(Requester) == false)
67 {
68 return;
69 }
70
71 const float CurrentTime = GetWorld()->GetTimeSeconds();
72 const bool bHadToken = RemoveAttackTokenHolder(Requester);
73
74 TokenCandidates.RemoveAll([Requester](const FEnemyAttackTokenCandidate& Candidate)
75 {
76 return Candidate.Requester.IsValid() == false || Candidate.Requester.Get() == Requester;
77 });
78
79 if (bHadToken)
80 {
81 FEnemyAttackTokenHistory& History = FindOrAddHistory(Requester);
82 History.LastReleaseTime = CurrentTime;
83 }
84
85 CompactTokenData(CurrentTime);
86 TryGrantAttackTokens(CurrentTime);
88}
FEnemyAttackTokenHistory & FindOrAddHistory(AActor *Requester)
Definition EnemyCombatSubsystem.cpp:188
void TryGrantAttackTokens(float CurrentTime)
Definition EnemyCombatSubsystem.cpp:218
bool RemoveAttackTokenHolder(AActor *Requester)
Definition EnemyCombatSubsystem.cpp:116
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ RemoveAttackTokenHolder()

bool UEnemyCombatSubsystem::RemoveAttackTokenHolder ( AActor *  Requester)
private
117{
118 bool bRemoved = false;
119
120 TokenHolders.RemoveAll([Requester, &bRemoved](const TWeakObjectPtr<AActor>& TokenHolder)
121 {
122 if (TokenHolder.IsValid() == false)
123 {
124 return true;
125 }
126
127 if (TokenHolder.Get() == Requester)
128 {
129 bRemoved = true;
130 return true;
131 }
132
133 return false;
134 });
135
136 return bRemoved;
137}
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ RequestAttackToken()

bool UEnemyCombatSubsystem::RequestAttackToken ( AActor *  TargetActor,
AActor *  Requester 
)
23{
24 if (IsValid(TargetActor) == false || IsValid(Requester) == false)
25 {
26 return false;
27 }
28
29 const float CurrentTime = GetWorld()->GetTimeSeconds();
30
31 CompactTokenData(CurrentTime);
32
33 if (HasAttackToken(Requester))
34 {
36 return true;
37 }
38
39 FindOrAddCandidate(TargetActor, Requester, CurrentTime);
40 TryGrantAttackTokens(CurrentTime);
42
43 return HasAttackToken(Requester);
44}
FEnemyAttackTokenCandidate & FindOrAddCandidate(AActor *TargetActor, AActor *Requester, float CurrentTime)
Definition EnemyCombatSubsystem.cpp:167
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ TryGrantAttackTokens()

void UEnemyCombatSubsystem::TryGrantAttackTokens ( float  CurrentTime)
private
219{
220 const int32 MaxTokenCount = GetDefault<UEnemyCombatSettings>()->GetMaxMeleeAttackTokenCount();
221
222 while (TokenHolders.Num() < MaxTokenCount && TokenCandidates.IsEmpty() == false)
223 {
224 int32 BestIndex = INDEX_NONE;
225 float BestScore = -FLT_MAX;
226
227 for (int32 Index = 0; Index < TokenCandidates.Num(); ++Index)
228 {
229 const float Score = CalculateCandidateScore(TokenCandidates[Index], CurrentTime);
230 if (Score > BestScore)
231 {
232 BestScore = Score;
233 BestIndex = Index;
234 }
235 }
236
237 if (BestIndex == INDEX_NONE)
238 {
239 return;
240 }
241
242 AActor* BestRequester = TokenCandidates[BestIndex].Requester.Get();
243 if (IsValid(BestRequester))
244 {
245 TokenHolders.Add(BestRequester);
246 }
247
248 TokenCandidates.RemoveAtSwap(BestIndex);
249 }
250}
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ UnregisterAttackTokenActor()

void UEnemyCombatSubsystem::UnregisterAttackTokenActor ( AActor *  Requester)
91{
92 if (IsValid(Requester) == false)
93 {
94 return;
95 }
96
97 const float CurrentTime = GetWorld()->GetTimeSeconds();
98
99 RemoveAttackTokenHolder(Requester);
100
101 TokenCandidates.RemoveAll([Requester](const FEnemyAttackTokenCandidate& Candidate)
102 {
103 return Candidate.Requester.IsValid() == false || Candidate.Requester.Get() == Requester;
104 });
105
106 TokenHistories.RemoveAll([Requester](const FEnemyAttackTokenHistory& History)
107 {
108 return History.Requester.IsValid() == false || History.Requester.Get() == Requester;
109 });
110
111 CompactTokenData(CurrentTime);
112 TryGrantAttackTokens(CurrentTime);
114}
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

멤버 데이터 문서화

◆ DebugTimerHandle

FTimerHandle UEnemyCombatSubsystem::DebugTimerHandle
private

◆ TokenCandidates

TArray<FEnemyAttackTokenCandidate> UEnemyCombatSubsystem::TokenCandidates
private

◆ TokenHistories

TArray<FEnemyAttackTokenHistory> UEnemyCombatSubsystem::TokenHistories
private

◆ TokenHolders

TArray<TWeakObjectPtr<AActor> > UEnemyCombatSubsystem::TokenHolders
private

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