KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
ULingoGameHelper.cpp
이 파일의 문서화 페이지로 가기
1// Copyright (c) 2025 Doppleddiggong. All rights reserved. Unauthorized copying, modification, or distribution of this file, via any medium is strictly prohibited. Proprietary and confidential.
2
3
4#include "ULingoGameHelper.h"
5
6#include "ALingoGameMode.h"
7#include "ALingoGameState.h"
8#include "ALingoPlayerState.h"
9#include "APlayerActor.h"
10#include "APlayerControl.h"
11#include "ASpeakStageActor.h"
12#include "AWheatly.h"
13#include "FColorStyleData.h"
15#include "Kismet/GameplayStatics.h"
16#include "Onepiece/Onepiece.h"
17
18
20{
21 return FDateTime::UtcNow().ToUnixTimestamp();
22}
23
24int32 ULingoGameHelper::GetUserId(const UObject* WorldContextObject)
25{
26 if ( auto PC = GetPlayerControl(WorldContextObject) )
27 return PC->GetUserId();
28 return 0;
29}
30
31int ULingoGameHelper::GetMultiPlayerCount(const UObject* WorldContextObject)
32{
33 ALingoGameState* GS = Cast<ALingoGameState>(UGameplayStatics::GetGameState(WorldContextObject));
34 int32 NumPlayers = GS ? GS->PlayerArray.Num() : 0;
35 return NumPlayers;
36}
37
38bool ULingoGameHelper::IsMultiPlay(const UObject* WorldContextObject)
39{
40 return GetMultiPlayerCount(WorldContextObject) > 1;
41}
42
43ALingoGameMode* ULingoGameHelper::GetLingoGameMode(const UObject* WorldContextObject)
44{
45 return WorldContextObject->GetWorld()->GetAuthGameMode<ALingoGameMode>();
46}
47
48ALingoGameState* ULingoGameHelper::GetLingoGameState(const UObject* WorldContextObject)
49{
50 return Cast<ALingoGameState>(UGameplayStatics::GetGameState(WorldContextObject));
51}
52
54{
55 if (!WorldContextObject)
56 return nullptr;
57
58 UWorld* World = WorldContextObject->GetWorld();
59 if (!World)
60 return nullptr;
61
62 APlayerController* PC = World->GetFirstPlayerController();
63 if (!PC)
64 return nullptr;
65
66 return Cast<ALingoPlayerState>(PC->PlayerState);
67}
68
70{
71 if (PC)
72 {
73 return PC->GetPlayerState<ALingoPlayerState>();
74 }
75 else
76 {
77 return nullptr;
78 }
79}
80
81
82TArray<ALingoPlayerState*> ULingoGameHelper::GetLingoPlayerStateList(const UObject* WorldContextObject)
83{
84 TArray<ALingoPlayerState*> PlayerStateList;
85 for (FConstPlayerControllerIterator It = WorldContextObject->GetWorld()->GetPlayerControllerIterator(); It; ++It)
86 {
87 if (APlayerController* PC = It->Get())
88 {
89 if (ALingoPlayerState* PS = PC->GetPlayerState<ALingoPlayerState>())
90 {
91 PlayerStateList.Add(PS);
92 }
93 }
94 }
95
96 return PlayerStateList;
97}
98
99bool ULingoGameHelper::IsLocalPlayerPawn(const UObject* WorldContextObject)
100{
101 const UWorld* World = WorldContextObject->GetWorld();
102 if (!World)
103 return false;
104
105 const APlayerController* PC = World->GetFirstPlayerController();
106 if (!PC)
107 return false;
108
109 const APawn* Pawn = PC->GetPawn();
110 return Pawn && Pawn->IsLocallyControlled();
111}
112
113APawn* ULingoGameHelper::GetLocalPawn(const UObject* WorldContextObject)
114{
115 if (const UWorld* World = WorldContextObject->GetWorld())
116 {
117 if (APlayerController* PC = World->GetFirstPlayerController())
118 {
119 APawn* Pawn = PC->GetPawn();
120 if (Pawn && Pawn->IsLocallyControlled())
121 {
122 return Pawn;
123 }
124 }
125 }
126 return nullptr;
127}
128
130{
131 switch (QuestType)
132 {
137
138 default: return "GameStart";
139 }
140}
141
143{
144 switch (QuestType)
145 {
150
151 default: return "GameEnd";
152 }
153}
154
156{
157 switch (QuestType)
158 {
159 case EQuestType::Read: return 1;
160 case EQuestType::Listen: return 2;
161 case EQuestType::Write: return 3;
162 case EQuestType::Speak: return 4;
163
164 default:
165 return 1;
166 }
167}
168
170{
171 return 300;
172}
173
175{
176 if (Score >= 90.0f)
178 else if (Score >= 80.0f)
180 else if (Score >= 70.0f)
182 else if (Score >= 60.0f)
184 else
186}
187
198
200{
201 if (ScenarioType == EScenarioType::READING) return EResourceTextureType::Read;
202 if (ScenarioType == EScenarioType::LISTENING) return EResourceTextureType::Listen;
203 if (ScenarioType == EScenarioType::SPEAKING) return EResourceTextureType::Speak;
204 if (ScenarioType == EScenarioType::WRITING) return EResourceTextureType::Write;
205
207}
208
209FString ULingoGameHelper::GetFormatTimer(const float InRemainTime )
210{
211 const int32 TotalMilliseconds = FMath::FloorToInt(InRemainTime * 1000.f);
212
213 const int32 Minutes = TotalMilliseconds / 60000;
214 const int32 Seconds = (TotalMilliseconds / 1000) % 60;
215 const int32 Milliseconds = (TotalMilliseconds % 1000) / 10;
216
217 // 00:00.00
218 return FString::Printf(TEXT("%02d:%02d.%02d"), Minutes, Seconds, Milliseconds);
219}
220
221void ULingoGameHelper::ShowMouseCursor(const UObject* WorldContextObject)
222{
223 if (!WorldContextObject)
224 return;
225
226 UWorld* World = WorldContextObject->GetWorld();
227 if (!World)
228 return;
229
230 APlayerController* PC = World->GetFirstPlayerController();
231 if (!PC)
232 return;
233
234 PC->bShowMouseCursor = true;
235 PC->SetInputMode(FInputModeGameAndUI());
236}
237
238void ULingoGameHelper::HideMouseCursor(const UObject* WorldContextObject)
239{
240 if (!WorldContextObject)
241 return;
242
243 UWorld* World = WorldContextObject->GetWorld();
244 if (!World)
245 return;
246
247 APlayerController* PC = World->GetFirstPlayerController();
248 if (!PC)
249 return;
250
251 PC->bShowMouseCursor = false;
252 PC->SetInputMode(FInputModeGameOnly());
253}
254
255APlayerActor* ULingoGameHelper::GetPlayerActor(const UObject* WorldContextObject)
256{
257 if (!WorldContextObject)
258 return nullptr;
259
260 UWorld* World = WorldContextObject->GetWorld();
261 if (!World)
262 return nullptr;
263
264 APlayerController* PC = World->GetFirstPlayerController();
265 if (!PC)
266 return nullptr;
267
268 return Cast<APlayerActor>(PC->GetPawn());
269}
270
271
272APlayerControl* ULingoGameHelper::GetPlayerControl(const UObject* WorldContextObject)
273{
274 if (!WorldContextObject)
275 return nullptr;
276
277 UWorld* World = WorldContextObject->GetWorld();
278 if (!World)
279 return nullptr;
280
281 return Cast<APlayerControl>(World->GetFirstPlayerController());
282}
283
285{
286 if (!WorldContextObject)
287 return nullptr;
288
289 UWorld* World = WorldContextObject->GetWorld();
290 if (!World)
291 return nullptr;
292
293 return Cast<ASpeakStageActor>(UGameplayStatics::GetActorOfClass(World, ASpeakStageActor::StaticClass()));
294}
295
296AWheatly* ULingoGameHelper::GetWheatly(const UObject* WorldContextObject)
297{
298 if (!WorldContextObject)
299 return nullptr;
300
301 UWorld* World = WorldContextObject->GetWorld();
302 if (!World)
303 return nullptr;
304
305 return Cast<AWheatly>(UGameplayStatics::GetActorOfClass(World, AWheatly::StaticClass()));
306}
307
309{
310 if (!PlayerState)
311 return TEXT("");
312
313 // PlayerState의 Owner(PlayerController)를 통해 UserInfo 이름 가져오기
314 if (APlayerController* PC = Cast<APlayerController>(PlayerState->GetOwner()))
315 {
316 if (APlayerControl* PlayerControl = Cast<APlayerControl>(PC))
317 {
318 FString UserName = PlayerControl->GetUserName();
319 if (!UserName.IsEmpty())
320 return UserName;
321 }
322 }
323
324 // Fallback: PlayerState의 기본 이름
325 return PlayerState->GetPlayerName();
326}
327
328FString ULingoGameHelper::GetTimeRank(float InTimeTaken)
329{
330 if (InTimeTaken <= 300)
331 return "C";
332 else if (InTimeTaken <= 240)
333 return "B";
334 else if (InTimeTaken <= 180)
335 return "A";
336 else
337 return "D";
338}
339
340FLinearColor ULingoGameHelper::GetRankColor(float InScore)
341{
342 if (InScore >= 90.0f)
343 {
344 // 1. Excellent (90 ~ 100): Green - 성공
345 return FLinearColor::Green;
346 }
347 else if (InScore >= 80.0f)
348 {
349 // 2. Good (80 ~ 89): LightGreen - 양호
350 return FLinearColor(0.56f, 1.0f, 0.56f, 1.0f);
351 }
352 else if (InScore >= 60.0f)
353 {
354 // 3. Average (60 ~ 79): Yellow - 주의
355 return FLinearColor::Yellow;
356 }
357 else if (InScore >= 40.0f)
358 {
359 // 4. Poor (40 ~ 59): Orange - 경고
360 return FLinearColor(1.0f, 0.5f, 0.0f, 1.0f);
361 }
362 else
363 {
364 // 5. Fail (0 ~ 39): Red - 심각한 실패
365 return FLinearColor::Red;
366 }
367}
368
370{
371 // 안정성 확보를 위해 입력값 범위 클램프 (0.0f ~ 100.0f)
372 InScore = FMath::Clamp(InScore, 0.0f, 100.0f);
373
374 if (InScore >= 90.0f)
375 {
376 // 1. Excellent (90 ~ 100): Green - 성공
378 }
379 else if (InScore >= 80.0f)
380 {
381 // 2. Good (80 ~ 89): LightGreen - 양호
383 }
384 else if (InScore >= 60.0f)
385 {
386 // 3. Average (60 ~ 79): Yellow - 주의
388 }
389 else if (InScore >= 40.0f)
390 {
391 // 4. Poor (40 ~ 59): Orange - 경고
393 }
394 else
395 {
396 // 5. Fail (0 ~ 39): Red - 심각한 실패
398 }
399}
400
401
403{
404 // 정답률 계산
405 const float Percentage = ((10.f - WrongCnt) / 10.f) * 100.f;
406 const int32 RoundedPercentage = FMath::RoundToInt(Percentage);
407
408 // FString으로 변환
409 return FString::Printf(TEXT("%d%%"), RoundedPercentage);
410}
EQuestType
Declares the player-controlled character actor.
APlayerControl 선언에 대한 Doxygen 주석을 제공합니다.
EColorStyleType
EResourceTextureType
EScenarioType
시나리오 타입 열거형
Main character driven directly by the player.
Speak Stage 시스템
Wheatly NPC 액터
Definition AWheatly.h:31
static int32 GetUserId(const UObject *WorldContextObject)
static class APlayerControl * GetPlayerControl(const UObject *WorldContextObject)
static FLinearColor GetRankColor(float InScore)
static int64 GetUnixTimestampInt64()
static class ALingoPlayerState * GetLingoPlayerStateByPC(const AController *PC)
static EResourceTextureType ConvertGradeScore(const float Score)
static int GetMultiPlayerCount(const UObject *WorldContextObject)
static int32 GetStageTypeIndex(const EQuestType QuestType)
static FString GetAccuracyPercentage(int WrongCnt)
static EResourceTextureType ConvertScenarioTexture(EScenarioType ScenarioType)
static void HideMouseCursor(const UObject *WorldContextObject)
마우스 커서를 숨기고 게임 전용 입력 모드로 설정합니다.
static bool IsLocalPlayerPawn(const UObject *WorldContextObject)
static FString GetStageStartMessage(const EQuestType QuestType)
static class ALingoPlayerState * GetLingoPlayerState(const UObject *WorldContextObject)
static FString GetFormatTimer(const float InRemainTime)
static FString GetPlayerNameFromState(const class ALingoPlayerState *PlayerState)
PlayerState에서 PlayerControl을 통해 사용자 이름 가져오기
static class ASpeakStageActor * GetSpeakStageActor(const UObject *WorldContextObject)
static class ALingoGameMode * GetLingoGameMode(const UObject *WorldContextObject)
static EResourceTextureType ConvertGradeString(const FString &Grade)
static float GetMissionPlayTime()
static TArray< class ALingoPlayerState * > GetLingoPlayerStateList(const UObject *WorldContextObject)
static EColorStyleType GetRankColorType(float InScore)
static APawn * GetLocalPawn(const UObject *WorldContextObject)
static class ALingoGameState * GetLingoGameState(const UObject *WorldContextObject)
static bool IsMultiPlay(const UObject *WorldContextObject)
static class AWheatly * GetWheatly(const UObject *WorldContextObject)
static FString GetTimeRank(float InTimeTaken)
static class APlayerActor * GetPlayerActor(const UObject *WorldContextObject)
첫 번째 플레이어의 PlayerActor를 가져옵니다.
static FString GetStageEndMessage(const EQuestType QuestType)
static void ShowMouseCursor(const UObject *WorldContextObject)
마우스 커서를 표시하고 게임+UI 입력 모드로 설정합니다.
static const FString ListenStageStart
Definition Onepiece.h:119
static const FString ReadStageEnd
Definition Onepiece.h:117
static const FString ReadStageStart
Definition Onepiece.h:116
static const FString WriteStageEnd
Definition Onepiece.h:123
static const FString WriteStageStart
Definition Onepiece.h:122
static const FString SpeakStageStart
Definition Onepiece.h:125
static const FString ListenStageEnd
Definition Onepiece.h:120
static const FString SpeakStageEnd
Definition Onepiece.h:126