2026-03-03 17:44:04 -05:00
# include "PlayerControllerBase.h"
# include "Common.h"
# include "Tangible.h"
# include "TangibleManager.h"
# include "Kismet/GameplayStatics.h"
# include "Engine/GameInstance.h"
2026-04-15 22:55:02 -04:00
# include "Engine/GameViewportClient.h"
# include "Framework/Application/SlateApplication.h"
# include "Widgets/SViewport.h"
# include "Slate/SObjectWidget.h"
FString AlxPlayerControllerBase : : GetUserWidgetName ( SWidget * W )
{
while ( W )
{
if ( W - > GetType ( ) = = FName ( " SObjectWidget " ) )
{
UUserWidget * UW = static_cast < SObjectWidget * > ( W ) - > GetWidgetObject ( ) ;
if ( UW ) return UW - > GetClass ( ) - > GetName ( ) ;
}
W = W - > GetParentWidget ( ) . Get ( ) ;
}
return TEXT ( " Unknown Widget " ) ;
}
2026-03-03 17:44:04 -05:00
AlxPlayerControllerBase * AlxPlayerControllerBase : : FromContext ( const UObject * Context )
{
APlayerController * PC = Context - > GetWorld ( ) - > GetFirstPlayerController ( ) ;
AlxPlayerControllerBase * Result = Cast < AlxPlayerControllerBase > ( PC ) ;
if ( Result = = nullptr )
{
UE_LOG ( LogLuprexIntegration , Fatal , TEXT ( " Not currently using a Luprex Player Controller. " ) ) ;
}
return Result ;
}
const FHitResult & AlxPlayerControllerBase : : GetLookAt ( const UObject * Context )
{
return FromContext ( Context ) - > CurrentLookAt ;
}
const AActor * AlxPlayerControllerBase : : GetLookAtActor ( const UObject * Context )
{
return FromContext ( Context ) - > CurrentLookAt . GetActor ( ) ;
}
void AlxPlayerControllerBase : : SetLookAt ( const UObject * Context , const FHitResult & HitResult )
{
AlxPlayerControllerBase * PC = FromContext ( Context ) ;
if ( PC - > CurrentLookAt . HitObjectHandle ! = HitResult . HitObjectHandle )
{
PC - > MustCallLookAtChanged = true ;
}
PC - > CurrentLookAt = HitResult ;
}
void AlxPlayerControllerBase : : SetLookAtChanged ( const UObject * Context )
{
AlxPlayerControllerBase * PC = FromContext ( Context ) ;
PC - > MustCallLookAtChanged = true ;
}
FVector2D AlxPlayerControllerBase : : GetLookAtPixel ( const UObject * Context )
{
AlxPlayerControllerBase * PC = FromContext ( Context ) ;
FVector2D ScreenPosition ;
if ( ! UGameplayStatics : : ProjectWorldToScreen ( PC , PC - > CurrentLookAt . Location , ScreenPosition , false ) )
{
return FVector2D ( ) ;
}
return ScreenPosition ;
}
2026-04-15 22:55:02 -04:00
void AlxPlayerControllerBase : : BeginPlay ( )
{
Super : : BeginPlay ( ) ;
2026-04-16 00:13:48 -04:00
HotkeyInputComponent = NewObject < UInputComponent > ( this ) ;
HotkeyInputComponent - > bBlockInput = false ;
PushInputComponent ( HotkeyInputComponent ) ;
2026-04-15 22:55:02 -04:00
}
void AlxPlayerControllerBase : : UpdateEventDispatch ( )
{
EventRequests . GarbageCollect ( ) ;
// If we're in GameOnly mode, check that focus is still on the viewport.
if ( CurrentInputMode = = InputMode : : GameOnly )
{
UGameViewportClient * GVC = GetWorld ( ) ? GetWorld ( ) - > GetGameViewport ( ) : nullptr ;
if ( GVC )
{
TSharedPtr < SViewport > ViewportWidget = GVC - > GetGameViewportWidget ( ) ;
if ( ViewportWidget . IsValid ( ) )
{
TSharedPtr < SWidget > Focused = FSlateApplication : : Get ( ) . GetKeyboardFocusedWidget ( ) ;
if ( Focused . Get ( ) ! = ViewportWidget . Get ( ) )
{
UE_LOG ( LogLuprexIntegration , Error , TEXT ( " In GameOnly mode, keyboard focus must stay on viewport, but was stolen by: %s. Restoring. " ) , * GetUserWidgetName ( Focused . Get ( ) ) ) ;
EventRequests . SetDirty ( ) ;
}
if ( ! ViewportWidget - > HasMouseCapture ( ) )
{
UE_LOG ( LogLuprexIntegration , Error , TEXT ( " In GameOnly mode, viewport must have mouse capture, but lost it. Restoring. " ) ) ;
EventRequests . SetDirty ( ) ;
}
}
}
}
if ( ! EventRequests . IsDirty ( ) ) return ;
EventRequests . ClearDirty ( ) ;
CurrentInputMode = EventRequests . GetRequestedMode ( ) ;
const TArray < FlxEventRequest > & Requests = EventRequests . GetRequests ( ) ;
if ( CurrentInputMode = = InputMode : : UIOnly )
{
SetInputMode ( FInputModeUIOnly ( ) . SetWidgetToFocus ( Requests [ 0 ] . Widget - > GetCachedWidget ( ) ) ) ;
}
else
{
SetInputMode ( FInputModeGameOnly ( ) ) ;
2026-04-16 00:13:48 -04:00
HotkeyInputComponent - > KeyBindings . Empty ( ) ;
2026-04-15 22:55:02 -04:00
TSet < FKey > BoundKeys ;
for ( const FlxEventRequest & Req : Requests )
{
for ( const FKey & Key : Req . Hotkeys )
{
if ( ! BoundKeys . Contains ( Key ) )
{
BoundKeys . Add ( Key ) ;
2026-04-16 00:13:48 -04:00
HotkeyInputComponent - > BindKey ( Key , IE_Pressed , this , & AlxPlayerControllerBase : : ForwardKeyEvent ) ;
2026-04-15 22:55:02 -04:00
}
}
}
}
}
void AlxPlayerControllerBase : : ForwardKeyEvent ( FKey Key )
{
// TODO: implement
}
void AlxPlayerControllerBase : : RequestEvents ( const FlxEventRequest & Request )
{
if ( ! FlxEventRequests : : SanityCheck ( Request ) ) return ;
AlxPlayerControllerBase * PC = FromContext ( Request . Widget ) ;
PC - > EventRequests . Request ( Request ) ;
}
void AlxPlayerControllerBase : : UnRequestEvents ( UUserWidget * Widget )
{
if ( Widget = = nullptr )
{
UE_LOG ( LogLuprexIntegration , Error , TEXT ( " UnRequestEvents called with null widget. " ) ) ;
return ;
}
AlxPlayerControllerBase * PC = FromContext ( Widget ) ;
PC - > EventRequests . Remove ( Widget ) ;
}
2026-03-03 17:44:04 -05:00
void AlxPlayerControllerBase : : UpdateLookAt ( )
{
UlxTangibleManager * TM = GetGameInstance ( ) - > GetSubsystem < UlxTangibleManager > ( ) ;
if ( TM = = nullptr ) return ;
UlxTangible * Possessed = TM - > GetPossessedTangible ( ) ;
if ( Possessed = = nullptr ) return ;
APawn * Pawn = GetPawn ( ) ;
if ( Pawn = = nullptr ) return ;
2026-03-12 19:12:37 -04:00
if ( Possessed - > GetActor ( ) ! = Cast < AActor > ( Pawn ) ) return ;
2026-03-03 17:44:04 -05:00
if ( PlayerCameraManager = = nullptr ) return ;
CalculateLookAt ( ) ;
if ( MustCallLookAtChanged )
{
MustCallLookAtChanged = false ;
LookAtChanged ( ) ;
}
}