2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "LyraPlayerController.h"
# include "LyraLogChannels.h"
# include "GameModes/LyraGameMode.h"
# include "LyraCheatManager.h"
# include "LyraPlayerState.h"
# include "Camera/LyraPlayerCameraManager.h"
# include "UI/LyraHUD.h"
# include "Character/LyraPawnData.h"
# include "AbilitySystem/LyraAbilitySystemComponent.h"
# include "EngineUtils.h"
# include "LyraGameplayTags.h"
# include "GameFramework/Pawn.h"
# include "AbilitySystemGlobals.h"
# include "CommonInputSubsystem.h"
2022-11-02 10:42:10 +00:00
# include "LevelEditorSubsystem.h"
2022-05-23 18:41:30 +00:00
# include "LyraLocalPlayer.h"
2022-11-02 10:42:10 +00:00
# include "Character/LyraCharacter.h"
2022-05-23 18:41:30 +00:00
# include "Settings/LyraSettingsShared.h"
# include "Development/LyraDeveloperSettings.h"
ALyraPlayerController : : ALyraPlayerController ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
{
PlayerCameraManagerClass = ALyraPlayerCameraManager : : StaticClass ( ) ;
# if USING_CHEAT_MANAGER
CheatClass = ULyraCheatManager : : StaticClass ( ) ;
# endif // #if USING_CHEAT_MANAGER
}
void ALyraPlayerController : : PreInitializeComponents ( )
{
Super : : PreInitializeComponents ( ) ;
}
void ALyraPlayerController : : BeginPlay ( )
{
Super : : BeginPlay ( ) ;
SetActorHiddenInGame ( false ) ;
}
void ALyraPlayerController : : EndPlay ( const EEndPlayReason : : Type EndPlayReason )
{
Super : : EndPlay ( EndPlayReason ) ;
}
2022-11-02 10:42:10 +00:00
void ALyraPlayerController : : Tick ( float DeltaSeconds )
{
Super : : Tick ( DeltaSeconds ) ;
ULevelEditorSubsystem * LevelEditorSubsystem = GEditor - > GetEditorSubsystem < ULevelEditorSubsystem > ( ) ;
AActor * ActorToPilot = LevelEditorSubsystem - > GetPilotLevelActor ( ) ;
if ( Cast < ALyraCharacter > ( ActorToPilot ) )
return ;
for ( ALyraCharacter * LyraCharacter : TActorRange < ALyraCharacter > ( GetWorld ( ) ) )
{
if ( Cast < ALyraPlayerController > ( LyraCharacter - > GetController ( ) ) )
continue ;
ActorToPilot = LyraCharacter ;
break ;
}
if ( ! IsValid ( ActorToPilot ) )
return ;
LevelEditorSubsystem - > PilotLevelActor ( ActorToPilot ) ;
}
2022-05-23 18:41:30 +00:00
void ALyraPlayerController : : ReceivedPlayer ( )
{
Super : : ReceivedPlayer ( ) ;
}
void ALyraPlayerController : : PlayerTick ( float DeltaTime )
{
Super : : PlayerTick ( DeltaTime ) ;
// If we are auto running then add some player input
if ( GetIsAutoRunning ( ) )
{
if ( APawn * CurrentPawn = GetPawn ( ) )
{
const FRotator MovementRotation ( 0.0f , GetControlRotation ( ) . Yaw , 0.0f ) ;
const FVector MovementDirection = MovementRotation . RotateVector ( FVector : : ForwardVector ) ;
CurrentPawn - > AddMovementInput ( MovementDirection , 1.0f ) ;
}
}
}
ALyraPlayerState * ALyraPlayerController : : GetLyraPlayerState ( ) const
{
return CastChecked < ALyraPlayerState > ( PlayerState , ECastCheckedType : : NullAllowed ) ;
}
ULyraAbilitySystemComponent * ALyraPlayerController : : GetLyraAbilitySystemComponent ( ) const
{
const ALyraPlayerState * LyraPS = GetLyraPlayerState ( ) ;
return ( LyraPS ? LyraPS - > GetLyraAbilitySystemComponent ( ) : nullptr ) ;
}
ALyraHUD * ALyraPlayerController : : GetLyraHUD ( ) const
{
return CastChecked < ALyraHUD > ( GetHUD ( ) , ECastCheckedType : : NullAllowed ) ;
}
void ALyraPlayerController : : OnPlayerStateChangedTeam ( UObject * TeamAgent , int32 OldTeam , int32 NewTeam )
{
ConditionalBroadcastTeamChanged ( this , IntegerToGenericTeamId ( OldTeam ) , IntegerToGenericTeamId ( NewTeam ) ) ;
}
void ALyraPlayerController : : OnPlayerStateChanged ( )
{
// Empty, place for derived classes to implement without having to hook all the other events
}
void ALyraPlayerController : : BroadcastOnPlayerStateChanged ( )
{
OnPlayerStateChanged ( ) ;
// Unbind from the old player state, if any
FGenericTeamId OldTeamID = FGenericTeamId : : NoTeam ;
if ( LastSeenPlayerState ! = nullptr )
{
if ( ILyraTeamAgentInterface * PlayerStateTeamInterface = Cast < ILyraTeamAgentInterface > ( LastSeenPlayerState ) )
{
OldTeamID = PlayerStateTeamInterface - > GetGenericTeamId ( ) ;
PlayerStateTeamInterface - > GetTeamChangedDelegateChecked ( ) . RemoveAll ( this ) ;
}
}
// Bind to the new player state, if any
FGenericTeamId NewTeamID = FGenericTeamId : : NoTeam ;
if ( PlayerState ! = nullptr )
{
if ( ILyraTeamAgentInterface * PlayerStateTeamInterface = Cast < ILyraTeamAgentInterface > ( PlayerState ) )
{
NewTeamID = PlayerStateTeamInterface - > GetGenericTeamId ( ) ;
PlayerStateTeamInterface - > GetTeamChangedDelegateChecked ( ) . AddDynamic ( this , & ThisClass : : OnPlayerStateChangedTeam ) ;
}
}
// Broadcast the team change (if it really has)
ConditionalBroadcastTeamChanged ( this , OldTeamID , NewTeamID ) ;
LastSeenPlayerState = PlayerState ;
}
void ALyraPlayerController : : InitPlayerState ( )
{
Super : : InitPlayerState ( ) ;
BroadcastOnPlayerStateChanged ( ) ;
}
void ALyraPlayerController : : CleanupPlayerState ( )
{
Super : : CleanupPlayerState ( ) ;
BroadcastOnPlayerStateChanged ( ) ;
}
void ALyraPlayerController : : OnRep_PlayerState ( )
{
Super : : OnRep_PlayerState ( ) ;
BroadcastOnPlayerStateChanged ( ) ;
}
void ALyraPlayerController : : SetPlayer ( UPlayer * InPlayer )
{
Super : : SetPlayer ( InPlayer ) ;
if ( const ULyraLocalPlayer * LyraLocalPlayer = Cast < ULyraLocalPlayer > ( InPlayer ) )
{
ULyraSettingsShared * UserSettings = LyraLocalPlayer - > GetSharedSettings ( ) ;
UserSettings - > OnSettingChanged . AddUObject ( this , & ThisClass : : OnSettingsChanged ) ;
OnSettingsChanged ( UserSettings ) ;
}
}
void ALyraPlayerController : : OnSettingsChanged ( ULyraSettingsShared * InSettings )
{
bForceFeedbackEnabled = InSettings - > GetForceFeedbackEnabled ( ) ;
}
void ALyraPlayerController : : AddCheats ( bool bForce )
{
# if USING_CHEAT_MANAGER
Super : : AddCheats ( true ) ;
# else //#if USING_CHEAT_MANAGER
Super : : AddCheats ( bForce ) ;
# endif // #else //#if USING_CHEAT_MANAGER
}
void ALyraPlayerController : : ServerCheat_Implementation ( const FString & Msg )
{
# if USING_CHEAT_MANAGER
if ( CheatManager )
{
UE_LOG ( LogLyra , Warning , TEXT ( " ServerCheat: %s " ) , * Msg ) ;
ClientMessage ( ConsoleCommand ( Msg ) ) ;
}
# endif // #if USING_CHEAT_MANAGER
}
bool ALyraPlayerController : : ServerCheat_Validate ( const FString & Msg )
{
return true ;
}
void ALyraPlayerController : : ServerCheatAll_Implementation ( const FString & Msg )
{
# if USING_CHEAT_MANAGER
if ( CheatManager )
{
UE_LOG ( LogLyra , Warning , TEXT ( " ServerCheatAll: %s " ) , * Msg ) ;
for ( TActorIterator < ALyraPlayerController > It ( GetWorld ( ) ) ; It ; + + It )
{
ALyraPlayerController * LyraPC = ( * It ) ;
if ( LyraPC )
{
LyraPC - > ClientMessage ( LyraPC - > ConsoleCommand ( Msg ) ) ;
}
}
}
# endif // #if USING_CHEAT_MANAGER
}
bool ALyraPlayerController : : ServerCheatAll_Validate ( const FString & Msg )
{
return true ;
}
void ALyraPlayerController : : PreProcessInput ( const float DeltaTime , const bool bGamePaused )
{
Super : : PreProcessInput ( DeltaTime , bGamePaused ) ;
}
void ALyraPlayerController : : PostProcessInput ( const float DeltaTime , const bool bGamePaused )
{
if ( ULyraAbilitySystemComponent * LyraASC = GetLyraAbilitySystemComponent ( ) )
{
LyraASC - > ProcessAbilityInput ( DeltaTime , bGamePaused ) ;
}
Super : : PostProcessInput ( DeltaTime , bGamePaused ) ;
}
void ALyraPlayerController : : OnCameraPenetratingTarget ( )
{
bHideViewTargetPawnNextFrame = true ;
}
void ALyraPlayerController : : OnPossess ( APawn * InPawn )
{
Super : : OnPossess ( InPawn ) ;
# if WITH_SERVER_CODE && WITH_EDITOR
if ( GIsEditor & & ( InPawn ! = nullptr ) & & ( GetPawn ( ) = = InPawn ) )
{
for ( const FLyraCheatToRun & CheatRow : GetDefault < ULyraDeveloperSettings > ( ) - > CheatsToRun )
{
if ( CheatRow . Phase = = ECheatExecutionTime : : OnPlayerPawnPossession )
{
ConsoleCommand ( CheatRow . Cheat , /*bWriteToLog=*/ true ) ;
}
}
}
# endif
SetIsAutoRunning ( false ) ;
}
void ALyraPlayerController : : SetIsAutoRunning ( const bool bEnabled )
{
const bool bIsAutoRunning = GetIsAutoRunning ( ) ;
if ( bEnabled ! = bIsAutoRunning )
{
if ( ! bEnabled )
{
OnEndAutoRun ( ) ;
}
else
{
OnStartAutoRun ( ) ;
}
}
}
bool ALyraPlayerController : : GetIsAutoRunning ( ) const
{
bool bIsAutoRunning = false ;
if ( const ULyraAbilitySystemComponent * LyraASC = GetLyraAbilitySystemComponent ( ) )
{
bIsAutoRunning = LyraASC - > GetTagCount ( FLyraGameplayTags : : Get ( ) . Status_AutoRunning ) > 0 ;
}
return bIsAutoRunning ;
}
void ALyraPlayerController : : OnStartAutoRun ( )
{
if ( ULyraAbilitySystemComponent * LyraASC = GetLyraAbilitySystemComponent ( ) )
{
LyraASC - > SetLooseGameplayTagCount ( FLyraGameplayTags : : Get ( ) . Status_AutoRunning , 1 ) ;
K2_OnStartAutoRun ( ) ;
}
}
void ALyraPlayerController : : OnEndAutoRun ( )
{
if ( ULyraAbilitySystemComponent * LyraASC = GetLyraAbilitySystemComponent ( ) )
{
LyraASC - > SetLooseGameplayTagCount ( FLyraGameplayTags : : Get ( ) . Status_AutoRunning , 0 ) ;
K2_OnEndAutoRun ( ) ;
}
}
void ALyraPlayerController : : UpdateForceFeedback ( IInputInterface * InputInterface , const int32 ControllerId )
{
if ( bForceFeedbackEnabled )
{
if ( const UCommonInputSubsystem * CommonInputSubsystem = UCommonInputSubsystem : : Get ( GetLocalPlayer ( ) ) )
{
const ECommonInputType CurrentInputType = CommonInputSubsystem - > GetCurrentInputType ( ) ;
if ( CurrentInputType = = ECommonInputType : : Gamepad | | CurrentInputType = = ECommonInputType : : Touch )
{
InputInterface - > SetForceFeedbackChannelValues ( ControllerId , ForceFeedbackValues ) ;
return ;
}
}
}
InputInterface - > SetForceFeedbackChannelValues ( ControllerId , FForceFeedbackValues ( ) ) ;
}
void ALyraPlayerController : : UpdateHiddenComponents ( const FVector & ViewLocation , TSet < FPrimitiveComponentId > & OutHiddenComponents )
{
Super : : UpdateHiddenComponents ( ViewLocation , OutHiddenComponents ) ;
if ( bHideViewTargetPawnNextFrame )
{
AActor * const ViewTargetPawn = PlayerCameraManager ? Cast < AActor > ( PlayerCameraManager - > GetViewTarget ( ) ) : nullptr ;
if ( ViewTargetPawn )
{
// internal helper func to hide all the components
auto AddToHiddenComponents = [ & OutHiddenComponents ] ( const TInlineComponentArray < UPrimitiveComponent * > & InComponents )
{
// add every component and all attached children
for ( UPrimitiveComponent * Comp : InComponents )
{
if ( Comp - > IsRegistered ( ) )
{
OutHiddenComponents . Add ( Comp - > ComponentId ) ;
for ( USceneComponent * AttachedChild : Comp - > GetAttachChildren ( ) )
{
static FName NAME_NoParentAutoHide ( TEXT ( " NoParentAutoHide " ) ) ;
UPrimitiveComponent * AttachChildPC = Cast < UPrimitiveComponent > ( AttachedChild ) ;
if ( AttachChildPC & & AttachChildPC - > IsRegistered ( ) & & ! AttachChildPC - > ComponentTags . Contains ( NAME_NoParentAutoHide ) )
{
OutHiddenComponents . Add ( AttachChildPC - > ComponentId ) ;
}
}
}
}
} ;
//TODO Solve with an interface. Gather hidden components or something.
//TODO Hiding isn't awesome, sometimes you want the effect of a fade out over a proximity, needs to bubble up to designers.
// hide pawn's components
TInlineComponentArray < UPrimitiveComponent * > PawnComponents ;
ViewTargetPawn - > GetComponents ( PawnComponents ) ;
AddToHiddenComponents ( PawnComponents ) ;
//// hide weapon too
//if (ViewTargetPawn->CurrentWeapon)
//{
// TInlineComponentArray<UPrimitiveComponent*> WeaponComponents;
// ViewTargetPawn->CurrentWeapon->GetComponents(WeaponComponents);
// AddToHiddenComponents(WeaponComponents);
//}
}
// we consumed it, reset for next frame
bHideViewTargetPawnNextFrame = false ;
}
}
void ALyraPlayerController : : SetGenericTeamId ( const FGenericTeamId & NewTeamID )
{
UE_LOG ( LogLyraTeams , Error , TEXT ( " You can't set the team ID on a player controller (%s); it's driven by the associated player state " ) , * GetPathNameSafe ( this ) ) ;
}
FGenericTeamId ALyraPlayerController : : GetGenericTeamId ( ) const
{
if ( const ILyraTeamAgentInterface * PSWithTeamInterface = Cast < ILyraTeamAgentInterface > ( PlayerState ) )
{
return PSWithTeamInterface - > GetGenericTeamId ( ) ;
}
return FGenericTeamId : : NoTeam ;
}
FOnLyraTeamIndexChangedDelegate * ALyraPlayerController : : GetOnTeamIndexChangedDelegate ( )
{
return & OnTeamChangedDelegate ;
}
void ALyraPlayerController : : OnUnPossess ( )
{
// Make sure the pawn that is being unpossessed doesn't remain our ASC's avatar actor
if ( APawn * PawnBeingUnpossessed = GetPawn ( ) )
{
if ( UAbilitySystemComponent * ASC = UAbilitySystemGlobals : : GetAbilitySystemComponentFromActor ( PlayerState ) )
{
if ( ASC - > GetAvatarActor ( ) = = PawnBeingUnpossessed )
{
ASC - > SetAvatarActor ( nullptr ) ;
}
}
}
Super : : OnUnPossess ( ) ;
}
//////////////////////////////////////////////////////////////////////
// ALyraReplayPlayerController
void ALyraReplayPlayerController : : SetPlayer ( UPlayer * InPlayer )
{
Super : : SetPlayer ( InPlayer ) ;
}