5#include "CoreMinimal.h"
6#include "GameFramework/PlayerController.h"
13#include "ProjectXPlayerController.generated.h"
15#define VIEW_TRACEDISTANCE 100000.0f
16#define CONN_SERVER_NOT_RESPONDING_SECONDS 6.0f
17#define CONN_BAD_PING 200
18#define CONN_BAD_RESPONSE_SECONDS 2.0f
19#define CONN_BAD_PACKET_LOSS 0.25f
20#define CONN_ALERT_DELAY 5.0f
21#define CONN_ALERT_RESTORE_DELAY 1.0f
22#define NUM_ACTORSTATE_SEND_PER_CHUNK 50
26class UKillCameraComponent;
76DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FHitPredictionSignature, AActor*, Victim, TSubclassOf<UWeaponInstance>,
Weapon,
bool, bHeadshot,
float,
Damage,
bool, bHealing);
84 GENERATED_UCLASS_BODY()
87 virtual APlayerState* GetOwnedPlayerState()
const override;
88 virtual int32 GetTeam()
const override;
89 UFUNCTION(BlueprintCallable, Category = PlayerController)
90 virtual UKillCameraComponent* GetKillCameraComponent()
const {
return KillCameraComponent; }
91 UFUNCTION(BlueprintCallable, Category = PlayerController)
95 UFUNCTION(BlueprintCallable, Category = PlayerController, DisplayName =
"Server Restart Player", meta = (ScriptName =
"ServerRestartPlayer"))
96 void K2_ServerRestartPlayer();
98 UFUNCTION(BlueprintPure, Category = PlayerController, DisplayName = "Can Restart Player", meta = (ScriptName = "CanRestartPlayer"))
99 bool K2_CanRestartPlayer() {
return CanRestartPlayer(); }
101 virtual void SetViewTargetWithBlend(
class AActor* NewViewTarget,
float BlendTime = 0,
enum EViewTargetBlendFunction BlendFunc = VTBlend_Linear,
float BlendExp = 0,
bool bLockOutgoing =
false);
102 virtual void SetControlRotation(
const FRotator& NewRotation);
103 virtual void UpdateRotation(
float DeltaTime);
104 virtual void ServerRestartPlayer_Implementation()
override;
105 virtual void ServerFinalizeRestartPlayer();
106 virtual bool CanRestartPlayer()
override;
107 virtual void ClientWasKicked_Implementation(
const FText& KickReason)
override;
108 virtual void SetupInputComponent()
override;
109 virtual void EndPlay(
const EEndPlayReason::Type EndPlayReason)
override;
110 virtual void BeginPlay()
override;
111 virtual void GetSeamlessTravelActorList(
bool bToEntry, TArray<class AActor*>& ActorList)
override;
112 virtual void Tick(
float DeltaSeconds)
override;
113 virtual void TickAimAssist(
const FVector& PawnLocation,
const FRotator& PawnRotation,
float DeltaTime);
114 virtual void TickCurrentViewHitResult(
const FVector& PawnLocation,
const FRotator& PawnRotation,
float DeltaTime);
115 virtual void TickConnectionQualityDetection(
float DeltaTime);
116 virtual void AddPitchInput(
float Val)
override;
117 virtual void AddYawInput(
float Val)
override;
118 virtual void AddRollInput(
float Val)
override;
119 virtual void ModifyViewAcceleration(
float Rate);
120 virtual void InteractPressed();
121 virtual void InteractReleased();
122 virtual void RequestRevive();
124 virtual void OnPossess(APawn* PawnToPossess)
override;
125 virtual void RespawnFromReviveBeacon();
126 virtual void AcceptRevive();
127 virtual void DeclineRevive();
129 virtual void ClearWaitingOnReviveState();
130 virtual void CloseRevivePrompt();
131 virtual class APlayerState* GetNextViewablePlayer(int32 dir)
override;
132 virtual void ServerViewNextPlayer_Implementation()
override;
133 virtual void ServerViewPrevPlayer_Implementation()
override;
134 UFUNCTION(Client, Reliable, WithValidation)
137 virtual
void SwitchToNextPlayer();
139 virtual
void SwitchToPreviousPlayer();
143 virtual
void PawnLeavingGame() override;
144 void OnNewPawn(APawn* NewPawh);
145 void InitializePlayerCosmeticRequestInfo();
146 void RequestCosmeticFromPlayer();
148 UFUNCTION(
Server, Reliable, WithValidation)
149 void Server_Reliable_RequestCosmeticFromPlayer(APlayerState* RequestedPlayerState);
151 UFUNCTION(BlueprintPure, Category = Bindings)
152 bool IsPlayerBindingNewButton()
const {
156 UFUNCTION(BlueprintPure, Category = Bindings)
157 bool IsPlayerHoldingControllerContextChangeButton()
const {
return bControllerContextChanged; }
158 void ApplyInputSettings();
159 UFUNCTION(BlueprintCallable)
160 void KeysRebound() {OnKeybindUpdatedEvent.Broadcast(); }
161 UFUNCTION(Client, Reliable)
162 void Client_ConfirmHitActor(AActor* Victim, UClass*
Weapon,
bool bHeadshot,
float Damage,
bool bHealing);
163 UFUNCTION(Client, Reliable)
164 void Client_RequestRedeploy();
165 UFUNCTION(Client, Reliable)
167 UFUNCTION(Client, Reliable)
169 UFUNCTION(BlueprintCallable)
170 void UpdateRadarSizeMultiplier(
float NewRadarSize);
171 UFUNCTION(BlueprintCallable, Category = Spectating)
172 void EnableSpectatorMode();
173 UFUNCTION(BlueprintImplementableEvent, Category = "
QuickChat")
174 void SpawnContextPing(FVector SpawnVector);
175 UFUNCTION(BlueprintCallable, Category = "Base Control")
177 UFUNCTION(BlueprintCallable, Category = "
Spawning")
178 bool SelectSpawnTarget(AActor* SpawnTarget);
179 UFUNCTION(BlueprintCallable, Category = "
Spawning")
180 bool SelectBestSpawnTarget(FVector TargetLocation,
bool bUseTargetLocation = false);
181 UFUNCTION(BlueprintCallable, Category = "
Spawning")
182 void ClearSpawnTarget();
183 UFUNCTION(BlueprintCallable, Category = "
Spawning")
184 void UpdateReviveTimeMultiplier(
float NewMultiplier) { ReviveTimeMultiplier = NewMultiplier; }
185 UFUNCTION(BlueprintCallable, Category =
"Spawning")
186 FORCEINLINE
float GetReviveTimeMultiplier()
const {
return ReviveTimeMultiplier; }
189 void StartPlayerTalking();
190 void StopPlayerTalking();
192 void ToggleFollowCam(
bool bFollowEnabled);
193 UFUNCTION(BlueprintCallable)
196 UFUNCTION(BlueprintCallable, Category = PlayerController)
197 bool ChangeTeam(uint8
Team);
198 UFUNCTION(BlueprintCallable, Category = PlayerController)
199 bool ChangeSquad(int32
Squad) { Server_Reliable_SelectSquad(
Squad);
return true; }
202 UFUNCTION(BlueprintCallable, Category = PlayerController)
203 virtual bool WaitingToPlayMatchStart();
208 void SetWelcomeMessage(
const FString& NewWelcomeMessage);
210 void SessionKickPlayer(
const FString& PlayerNameOrID,
const FString& Reason);
212 void KickPlayer(
const FString& PlayerNameOrID,
const FString& Reason);
214 void BanPlayer(
const FString& PlayerNameOrID,
const FString& Reason);
216 void ReportPlayer(
const FString& PlayerNameOrID,
const FString& Reason);
218 void FlySpeed(
const float NewFlySpeed = 1000.0f);
220 void GetMusicTrack();
222 void SmoothCam(
const float NewSmoothCamSpeed = -1.0f);
234 void PermanentInvisibility();
236 void IncrementPlayerStat(int8 EnumElement, int32 NumToAdd, int32 DebugMapType, FString
MapName);
237 UFUNCTION(
Server, Reliable, WithValidation)
239 UFUNCTION(
Server,Reliable,WithValidation)
240 void Server_Reliable_RespawnFromReviveBeacon();
241 UFUNCTION(
Server, Reliable, WithValidation)
242 void Server_Reliable_DeclineRevive();
244 UFUNCTION(
Server, Reliable, WithValidation)
245 virtual
void Server_Reliable_LeaveVehicle();
247 UFUNCTION(
Server, Reliable, WithValidation)
248 void Server_AntiCheatMessage(const TArray<uint8>& Message);
250 UFUNCTION(Client, Reliable)
251 void Client_AntiCheatMessage(const TArray<uint8>& Message);
252 UFUNCTION(BlueprintCallable)
253 void MatchStartRequest(){Server_Reliable_MatchStartRequest(); }
254 UFUNCTION(BlueprintCallable)
255 void ToggleReadyStatus(
bool bReady);
256 UFUNCTION(BlueprintCallable, Category = PlayerController)
257 static void SendHitConfirm(AActor* Victim,
float Damage,
struct FDamageEvent
const& DamageEvent, AController* EventInstigator, AActor* DamageCauser,
bool bHealing);
260 virtual
void OnRep_KillCameraClass();
261 virtual
void OnRep_Pawn() override;
262 virtual
void OnRep_PlayerState() override;
265 virtual
void VoteYes();
267 virtual
void VoteNo();
269 virtual
void ToggleMap();
270 UFUNCTION(BlueprintCallable, Category = "PlayerController")
271 virtual
void ResetIdleTimer();
273 void WaitForInitialHud();
275 void FocusReviveBeacon(
float BlendTime);
276 void OnInitialHudReady();
278 virtual void CloseChat();
279 template<
bool bNewToggle>
280 void ToggleControllerContextChange();
283 UFUNCTION(BlueprintPure)
286 UFUNCTION(BlueprintPure)
288 virtual void LeaveVehicle();
290 UFUNCTION(
Server, WithValidation, Reliable)
293 UFUNCTION(
Server, WithValidation, Reliable)
297 UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "
Debug")
298 bool bTravelIfGameOverInEditor = false;
300 UPROPERTY(BlueprintAssignable, Category = "Push To Talk Events")
301 FPlayerSpeakSignature OnPlayerStartedSpeaking;
302 UPROPERTY(BlueprintAssignable, Category = "Push To Talk Events")
303 FPlayerSpeakSignature OnPlayerStoppedSpeaking;
304 UPROPERTY(BlueprintAssignable, Category = "Game Events")
305 FVictorySignature OnPlayerVictory;
306 UPROPERTY(BlueprintAssignable)
307 FOnInteractSignature OnInteract;
308 UPROPERTY(BlueprintAssignable)
309 FOnInteractComplete OnInteractComplete;
310 UPROPERTY(BlueprintAssignable, Category = "Game Events")
311 FIdlePlayerSignature OnIdlePlayerWarning;
312 UPROPERTY(BlueprintAssignable, Category = "Game Events")
313 FOnTeamChangeResponseReceived OnTeamChangeResponseReceived;
314 UPROPERTY(BlueprintAssignable, Category = "Game Events")
315 FIdlePlayerSignature OnIdlePlayerStopWarning;
316 UPROPERTY(BlueprintAssignable, Category = "Game Events")
317 FGamePadStateChangeSignature OnGamepadStateChanged;
318 UPROPERTY(BlueprintAssignable, Category = "Game Events")
319 FNewPawnSignature OnPawnChanged;
320 UPROPERTY(BlueprintAssignable, Category = "Network Events")
321 FOnConnectionStatusChangedSignature OnBadConnectionDetected;
322 UPROPERTY(BlueprintAssignable, Category = "Network Events")
323 FOnConnectionStatusChangedSignature OnGoodConnectionDetected;
324 UPROPERTY(BlueprintAssignable, Category = "Network Events")
325 FOnConnectionStatusChangedSignature OnServerNotRespondingDetected;
326 UPROPERTY(BlueprintAssignable, Category = "Network Events")
327 FOnConnectionStatusChangedSignature OnServerRespondingDetected;
328 UPROPERTY(BlueprintAssignable, Category = "Generic Events")
329 FNewHudCreatedSignature OnNewHUDCreatedAndReady;
330 UPROPERTY(BlueprintAssignable, Category = "Generic Events")
331 FPlayerErrorSignature OnPlayerError;
332 UPROPERTY(BlueprintAssignable, Category = "Player Restart Events")
333 FRestartFailureSignature OnServerRestartPlayerFailure;
334 UPROPERTY(BlueprintAssignable, Category = "Player Restart Events")
335 FOnPlayerRestartEvent OnPlayerRestartRequested;
336 UPROPERTY(BlueprintAssignable, Category = "Targeting Events")
337 FOnCharacterTargetedSignature OnPlayerTargetedStartedEvent;
338 UPROPERTY(BlueprintAssignable, Category = "Targeting Events")
339 FOnCharacterTargetedSignature OnPlayerTargetedStoppedEvent;
340 UPROPERTY(BlueprintAssignable)
341 FOnKeyBindingUpdatedSignature OnKeybindUpdatedEvent;
342 FViewRotationUpdateEvent ViewRotationUpdateEvent;
343 UPROPERTY(BlueprintAssignable, Category = "
Weapon Events")
344 FHitPredictionSignature OnClientHitPrediction;
345 UPROPERTY(BlueprintAssignable, Category = "
Radar")
346 FOnRadarSizeUpdatedSignature OnRadarSizeMultiplierUpdated;
347 UPROPERTY(BlueprintAssignable, Category = "GameEvents")
348 FGenericDelegateSignature OnServerRequestedRedeploy;
349 UPROPERTY(BlueprintAssignable, Category = "GameEvents")
350 FOnPlayerKickedSignature OnPlayerKicked;
351 UPROPERTY(BlueprintAssignable, Category = "GameEvents")
352 FOnPlayerFollowedSignature OnFollowPlayerUpdatedEvent;
353 UPROPERTY(BlueprintAssignable, Category = "GameEvents")
354 FOnWarnPlayerIdle OnWarnPlayerIdle;
357 bool bClientIdleWarned = false;
358 bool ServerStatTracking = false;
360 UPROPERTY(BlueprintReadOnly)
361 float RadarSizeMultiplier = 1.0f;
366 float RedeployModifier = 0.0f;
367 bool bSetRedeployTimer = false;
368 bool bIsRedeploying = false;
370 UFUNCTION(BlueprintCallable,BlueprintPure)
371 FORCEINLINE UVivoxPlayerComponent* GetVivoxComponent()
const {
return VivoxPlayerComponent; }
373 void SetAimAssistConfiguration(UCurveFloat*
const FallOffCurve, FVector2D Angle);
374 void SetLookSensitivityMultiplier(
float Multiplier);
376 void RegisterWithAntiCheat();
377 void UnregisterWithAntiCheat();
379 UFUNCTION(Client, Reliable)
380 void Client_EndSession();
381 UFUNCTION(Client, Reliable)
382 void Client_BeginSession();
389 class UKillCameraComponent* KillCameraComponent = NULL;
391 UPROPERTY(ReplicatedUsing = OnRep_KillCameraClass, EditDefaultsOnly, Category =
Kill)
392 TSubclassOf<class UKillCameraComponent> KillCameraClass = NULL;
394 UPROPERTY(EditDefaultsOnly, Category = DamageType)
395 TSubclassOf<UDamageType> SuicideDamageType;
397 UPROPERTY(GlobalConfig)
398 TSubclassOf<class UKillCameraComponent> KillCameraClassOverride = NULL;
399 UPROPERTY(GlobalConfig)
400 int32 IdleTimeoutTime = 120;
402 UPROPERTY(EditDefaultsOnly, GlobalConfig, Category = "Menus")
403 float MapOpenDelay = 2.f;
404 UPROPERTY(EditDefaultsOnly)
405 UVivoxPlayerComponent* VivoxPlayerComponent = NULL;
407 UFUNCTION(
Server, Reliable)
408 void Server_RequestActorStateInfo();
409 UFUNCTION(
Server, Reliable, WithValidation)
410 void Server_Reliable_SelectTeam(uint8
Team);
411 UFUNCTION(
Server, Reliable, WithValidation)
412 void Server_Reliable_SelectSquad(int32
Squad);
413 UFUNCTION(
Server, Reliable, WithValidation)
414 void Server_Reliable_AutoAssignSquad();
415 UFUNCTION(Client, Reliable, WithValidation)
417 UFUNCTION(Client, Reliable, WithValidation)
418 virtual
void Client_WarnIdlePlayerToggle(
bool bWarn);
419 UFUNCTION(Client, Reliable, WithValidation)
420 virtual
void Client_EarlyWarnIdlePlayer();
421 virtual
void ClientSetHUD_Implementation(TSubclassOf<AHUD> NewHUDClass) override;
423 UFUNCTION(
Server, Reliable, WithValidation)
424 virtual
void Server_ResetIdleTimer();
427 virtual
void WarnIdlePlayerToggle(
bool bWarning);
429 virtual
void IdlePlayerTimeout();
430 virtual
void ResetIdleTimerIfNeeded();
431 UFUNCTION(BlueprintCallable)
432 virtual
void ResetIdleTimerUI();
434 virtual
void ToggleTeamChat();
435 virtual
void ToggleChat();
436 void SendContextPing();
437 virtual
void UpdatePlayerTargeting(const FVector& PawnLocation, const FRotator& PawnRotation,
float DeltaSeconds);
438 UFUNCTION(
Server, Reliable, WithValidation)
439 void Server_Reliable_SelectSpawnTarget(AActor* SpawnTarget);
440 UFUNCTION(
Server, Reliable, WithValidation)
441 void Server_Reliable_ClearSpawnTarget();
442 UFUNCTION(
Server, Reliable, WithValidation)
443 void Server_Reliable_ReadyStatusUpdated(
bool bReady);
444 UFUNCTION(
Server, Reliable, WithValidation)
445 void Server_Reliable_MatchStartRequest();
446 UFUNCTION(BlueprintCallable,
Server, Reliable, Category = PlayerController)
447 void Server_RedeployCharacter();
449 TArray<AActor*> GetIgnoredAimAssistActors();
453 bool bWaitingToPlayMatchStart = true;
456 UPROPERTY(EditDefaultsOnly)
457 float AimAssistFriction = 0.6f;
459 UPROPERTY(EditDefaultsOnly)
460 float AimAssistAdhesion = 5.0f;
462 UPROPERTY(EditDefaultsOnly)
463 float TurnRateAccelerationRate = 5.0f;
465 UPROPERTY(EditDefaultsOnly)
466 float TurnRateDeccelerationRate = 10.0f;
468 UPROPERTY(EditDefaultsOnly)
469 float TurnRateAccelerationMax = 5.0f;
471 UPROPERTY(EditDefaultsOnly)
472 float RequestHelpDelay = 5.0f;
473 UPROPERTY(EditDefaultsOnly)
474 UCurveFloat* DefaultAutoAimFalloffCurve =
nullptr;
475 UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "UI", meta = (AllowPrivateAccess = true))
477 UPROPERTY(EditDefaultsOnly)
481 TArray<TWeakObjectPtr<AActor>> PlayersToIgnore;
483 TArray<TWeakObjectPtr<APlayerState>>PlayerToLoadCosmetics;
487 bool bIsBinding = false;
488 bool bIsFollowingPlayer = false;
489 bool bControllerContextChanged = false;
490 UCurveFloat* AutoAimFalloffCurve =
nullptr;
491 FVector2D AimAssistAngle = FVector2D(15.0f, 30.0f);
492 float ViewAccelerationCooldown = 0.0f;
493 float ViewRotationMultiplier = 1.0f;
494 float ViewAccelerationMultiplier = 1.0f;
495 float LastKnownYaw = 0.f;
496 float LastKnownPitch = 0.f;
497 float ReviveTimeMultiplier = 1.0f;
498 bool bIncludeAlliesInAimAssistHitResult = false;
499 FHitResult AimAssistHitResult;
500 FHitResult CurrentViewHitResult;
501 FHitResult VisibilityHitResult;
502 FHitResult TargetingHitResult;
503 static FHitResult EmptyViewHitResult;
504 static TArray<FHitResult> EmptyTargetingHitResult;
505 static TArray<TWeakObjectPtr<AActor>> EmptyActorArray;
507 TArray<TWeakObjectPtr<AActor>> TargetedActors;
509 TArray<FHitResult> TargetingHits;
510 FTimerHandle InitialHudTimer;
511 FTimerHandle LeaveVehicleTimer;
512 FTimerHandle IdlePlayerTimer;
513 FTimerHandle IdlePlayerWarningTimer;
514 FTimerHandle IdlePlayerFifteenSecondWarningTimer;
515 FTimerHandle ArmoryIdleResetTimer;
517 bool bHasDeployedAtLeastOnce = false;
518 float LastRequestedHelpTime = 0.0f;
519 float AvgLostPacketPctIn = 0.0f;
520 float AvgLostPacketPctOut = 0.0f;
521 bool ServerNotResponding = 0.0f;
522 float LastGoodConnectionTime = 0.0f;
523 float LastBadConnectionTime = 0.0f;
524 float IdleTimerResetCooldownTime = 2.0f;
525 TArray<UObject*> HiddenWidgets;
526 FRotator DesiredControlRotation = FRotator::ZeroRotator;
527 float LookSensitivityRuntimeMultiplier = 1.0f;
528 FVector FollowComponentTargetRelativeLocation = FVector::ZeroVector;
529 bool bRegisteredWithAntiCheat = false;
531 bool bRequestedActorStateInfo = false;
532 void SendActorStateInfoToClient();
538 UFUNCTION(BlueprintPure)
539 static const FHitResult& GetPlayerViewHitResult(UObject* const WorldContextObject);
541 UFUNCTION(BlueprintPure)
542 static const FHitResult& GetPlayerAimAssistHitResult(UObject* const WorldContextObject);
544 UFUNCTION(BlueprintPure)
545 static const TArray<FHitResult>& GetTargetingHitResult(UObject* const WorldContextObject);
546 UFUNCTION(BlueprintPure)
547 static const TArray<AActor*> GetTargetedActors(UObject* const WorldContextObject);
549 static const TArray<TWeakObjectPtr<AActor>>& GetTargets(UObject* const WorldContextObject);
551 virtual
void CurrentViewHitResultInDistance(const
float Distance, FHitResult& ReturnHitResult);
554 bool bFPMeshesVisible = true;
555 float SmoothCamSpeed = -1.0f;
556 bool bRestartingPlayer = false;
559 UPROPERTY(EditAnywhere, BlueprintReadWrite, config, Category = PlayerController)
560 float InputADSYawScale;
563 UPROPERTY(EditAnywhere, BlueprintReadWrite, config, Category = PlayerController)
564 float InputADSPitchScale;
567 UPROPERTY(EditDefaultsOnly, Category = PlayerController)
570 int8 DebugGrenadeKillStat = 99;
ETeamJoinResponse
Definition: ProjectXGameMode.h:38
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FHitPredictionSignature, AActor *, Victim, TSubclassOf< UWeaponInstance >, Weapon, bool, bHeadshot, float, Damage, bool, bHealing)
DECLARE_EVENT_FourParams(AProjectXPlayerController, FViewRotationUpdateEvent, float, FRotator &, FRotator &, bool &)
EPlayerError
Definition: ProjectXPlayerController.h:39
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FKillParticipationSignature, AActor *, Victim, float, Damage, bool, bKiller)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPlayerErrorSignature, EPlayerError, Error)
ESpawnError
Definition: ProjectXPlayerController.h:46
@ InvalidPlayerController
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnWarnPlayerIdle)
Definition: ProjectXCharacter.h:128
Definition: ProjectXPlayerController.h:83
void RequestAutoAssignSquad()
Definition: ProjectXPlayerController.h:200
FORCEINLINE bool GetHasDeployedAtLeastOnce() const
Definition: ProjectXPlayerController.h:187
void SetHasDeployedAtLeastOnce(bool bHasDeployed)
Definition: ProjectXPlayerController.h:188
Definition: ProjectXPlayerState.h:238
Definition: ProjectXRecordingPawn.h:15
Definition: ProjectXVehicle.h:56
Definition: OwnedInterface.h:20
Definition: TeamInterface.h:26
Definition: FOVCameraModifier.h:12
Definition: MapRotationReceiverComponent.h:11
Definition: ProjectXDamageType.h:62
Definition: ProjectXGameViewportClient.h:23
bool IsPlayerBindingNewButton() const
Definition: ProjectXGameViewportClient.h:51
Definition: CosmeticAssetBase.h:36
Definition: ProjectX.h:43