Players can host or join via Steam or LAN, pick maps, and connect by address; dedicated servers expose an HTTP panel for port and game rules. Co-authored-by: Cursor <cursoragent@cursor.com>
312 lines
11 KiB
C++
312 lines
11 KiB
C++
// Copyright VocationLife Project. All Rights Reserved.
|
|
|
|
#include "VocationPlayerController.h"
|
|
#include "VocationCharacter.h"
|
|
#include "VocationHUD.h"
|
|
#include "VocationSessionSubsystem.h"
|
|
#include "VocationGameInstance.h"
|
|
#include "VocationMainMenuWidget.h"
|
|
#include "EnhancedInputComponent.h"
|
|
#include "EnhancedInputSubsystems.h"
|
|
#include "InputAction.h"
|
|
#include "InputMappingContext.h"
|
|
#include "InputCoreTypes.h"
|
|
#include "Blueprint/UserWidget.h"
|
|
#include "Kismet/GameplayStatics.h"
|
|
|
|
AVocationPlayerController::AVocationPlayerController()
|
|
{
|
|
}
|
|
|
|
void AVocationPlayerController::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
|
|
CreateRuntimeInputAssets();
|
|
|
|
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
|
|
{
|
|
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
|
|
LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
|
|
{
|
|
Subsystem->AddMappingContext(SharedMappingContext, SharedMappingPriority);
|
|
Subsystem->AddMappingContext(TopDownMappingContext, ModeMappingPriority);
|
|
}
|
|
}
|
|
|
|
if (AVocationHUD* HUD = Cast<AVocationHUD>(GetHUD()))
|
|
{
|
|
VocationHUD = HUD;
|
|
}
|
|
|
|
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
|
{
|
|
GI->SetGraphicsPreset(GI->GetGraphicsPreset(), GI->IsRayTracingEnabled());
|
|
}
|
|
|
|
// Show multiplayer menu on first load (local player only).
|
|
if (IsLocalController() && !IsRunningDedicatedServer())
|
|
{
|
|
ToggleMultiplayerMenu();
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::SetupInputComponent()
|
|
{
|
|
Super::SetupInputComponent();
|
|
|
|
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(InputComponent))
|
|
{
|
|
if (AVocationCharacter* Character = Cast<AVocationCharacter>(GetPawn()))
|
|
{
|
|
EnhancedInput->BindAction(MoveAction, ETriggerEvent::Triggered, Character, &AVocationCharacter::HandleMove);
|
|
EnhancedInput->BindAction(LookAction, ETriggerEvent::Triggered, Character, &AVocationCharacter::HandleLook);
|
|
EnhancedInput->BindAction(JumpAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleJumpStarted);
|
|
EnhancedInput->BindAction(InteractAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleInteract);
|
|
EnhancedInput->BindAction(AttackAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleAttack);
|
|
EnhancedInput->BindAction(ToggleCameraAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleToggleCamera);
|
|
EnhancedInput->BindAction(InventoryAction, ETriggerEvent::Started, Character, &AVocationCharacter::HandleInventory);
|
|
EnhancedInput->BindAction(PauseAction, ETriggerEvent::Started, this, &AVocationPlayerController::TogglePauseMenu);
|
|
}
|
|
}
|
|
|
|
InputComponent->BindKey(EKeys::F1, IE_Pressed, this, &AVocationPlayerController::ApplyLowGraphics).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::F2, IE_Pressed, this, &AVocationPlayerController::ApplyMediumGraphics).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::F3, IE_Pressed, this, &AVocationPlayerController::ApplyHighGraphics).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::F4, IE_Pressed, this, &AVocationPlayerController::ApplyUltraGraphics).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::F5, IE_Pressed, this, &AVocationPlayerController::ApplyRayTracingGraphics).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::M, IE_Pressed, this, &AVocationPlayerController::ToggleMultiplayerMenu).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::H, IE_Pressed, this, &AVocationPlayerController::HostCoopGame).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::J, IE_Pressed, this, &AVocationPlayerController::JoinFirstFoundSession).bConsumeInput = false;
|
|
InputComponent->BindKey(EKeys::S, IE_Pressed, this, &AVocationPlayerController::QuickSave).bConsumeInput = false;
|
|
}
|
|
|
|
void AVocationPlayerController::OnPossess(APawn* InPawn)
|
|
{
|
|
Super::OnPossess(InPawn);
|
|
SetupInputComponent();
|
|
|
|
if (AVocationCharacter* Character = Cast<AVocationCharacter>(InPawn))
|
|
{
|
|
ApplyInputMappingForCameraMode(Character->GetCameraMode());
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::TogglePauseMenu()
|
|
{
|
|
bPauseMenuOpen = !bPauseMenuOpen;
|
|
SetPause(bPauseMenuOpen);
|
|
if (VocationHUD)
|
|
{
|
|
VocationHUD->SetPauseVisible(bPauseMenuOpen);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ShowInteractionPrompt(const FText& Prompt)
|
|
{
|
|
if (VocationHUD)
|
|
{
|
|
VocationHUD->SetInteractionPrompt(Prompt);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ClearInteractionPrompt()
|
|
{
|
|
if (VocationHUD)
|
|
{
|
|
VocationHUD->ClearInteractionPrompt();
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ToggleMultiplayerMenu()
|
|
{
|
|
if (MultiplayerMenu && MultiplayerMenu->IsInViewport())
|
|
{
|
|
MultiplayerMenu->RemoveFromParent();
|
|
bShowMouseCursor = false;
|
|
SetInputMode(FInputModeGameOnly());
|
|
return;
|
|
}
|
|
|
|
MultiplayerMenu = CreateWidget<UVocationMainMenuWidget>(this, UVocationMainMenuWidget::StaticClass());
|
|
if (MultiplayerMenu)
|
|
{
|
|
MultiplayerMenu->AddToViewport(100);
|
|
bShowMouseCursor = true;
|
|
FInputModeGameAndUI Mode;
|
|
Mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
|
|
Mode.SetHideCursorDuringCapture(false);
|
|
SetInputMode(Mode);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::HostCoopGame()
|
|
{
|
|
if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem<UVocationSessionSubsystem>())
|
|
{
|
|
Sessions->HostSession(4, TEXT("VocationLife"), TEXT("/Engine/Maps/Entry"), 7777, EVocationNetBackend::Auto, false);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::FindCoopGames()
|
|
{
|
|
if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem<UVocationSessionSubsystem>())
|
|
{
|
|
Sessions->FindSessions();
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::JoinCoopGame(int32 SessionIndex)
|
|
{
|
|
if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem<UVocationSessionSubsystem>())
|
|
{
|
|
Sessions->JoinSessionByIndex(SessionIndex);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ApplyInputMappingForCameraMode(EVocationCameraMode CameraMode)
|
|
{
|
|
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
|
|
{
|
|
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
|
|
LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
|
|
{
|
|
Subsystem->RemoveMappingContext(FirstPersonMappingContext);
|
|
Subsystem->RemoveMappingContext(TopDownMappingContext);
|
|
|
|
if (CameraMode == EVocationCameraMode::FirstPerson)
|
|
{
|
|
Subsystem->AddMappingContext(FirstPersonMappingContext, ModeMappingPriority);
|
|
}
|
|
else
|
|
{
|
|
Subsystem->AddMappingContext(TopDownMappingContext, ModeMappingPriority);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::CreateRuntimeInputAssets()
|
|
{
|
|
MoveAction = NewObject<UInputAction>(this, TEXT("IA_Move"));
|
|
MoveAction->ValueType = EInputActionValueType::Axis2D;
|
|
|
|
LookAction = NewObject<UInputAction>(this, TEXT("IA_Look"));
|
|
LookAction->ValueType = EInputActionValueType::Axis2D;
|
|
|
|
JumpAction = NewObject<UInputAction>(this, TEXT("IA_Jump"));
|
|
InteractAction = NewObject<UInputAction>(this, TEXT("IA_Interact"));
|
|
AttackAction = NewObject<UInputAction>(this, TEXT("IA_Attack"));
|
|
ToggleCameraAction = NewObject<UInputAction>(this, TEXT("IA_ToggleCamera"));
|
|
InventoryAction = NewObject<UInputAction>(this, TEXT("IA_Inventory"));
|
|
PauseAction = NewObject<UInputAction>(this, TEXT("IA_Pause"));
|
|
|
|
SharedMappingContext = NewObject<UInputMappingContext>(this, TEXT("IMC_Vocation_Shared"));
|
|
SharedMappingContext->MapKey(JumpAction, EKeys::SpaceBar);
|
|
SharedMappingContext->MapKey(InteractAction, EKeys::E);
|
|
SharedMappingContext->MapKey(AttackAction, EKeys::LeftMouseButton);
|
|
SharedMappingContext->MapKey(ToggleCameraAction, EKeys::C);
|
|
SharedMappingContext->MapKey(InventoryAction, EKeys::I);
|
|
SharedMappingContext->MapKey(PauseAction, EKeys::Escape);
|
|
SharedMappingContext->MapKey(JumpAction, EKeys::Gamepad_FaceButton_Bottom);
|
|
SharedMappingContext->MapKey(InteractAction, EKeys::Gamepad_FaceButton_Left);
|
|
SharedMappingContext->MapKey(AttackAction, EKeys::Gamepad_RightTrigger);
|
|
SharedMappingContext->MapKey(ToggleCameraAction, EKeys::Gamepad_Special_Right);
|
|
SharedMappingContext->MapKey(InventoryAction, EKeys::Gamepad_FaceButton_Top);
|
|
SharedMappingContext->MapKey(PauseAction, EKeys::Gamepad_Special_Left);
|
|
|
|
FirstPersonMappingContext = NewObject<UInputMappingContext>(this, TEXT("IMC_Vocation_FP"));
|
|
FirstPersonMappingContext->MapKey(MoveAction, EKeys::W);
|
|
FirstPersonMappingContext->MapKey(MoveAction, EKeys::S);
|
|
FirstPersonMappingContext->MapKey(MoveAction, EKeys::A);
|
|
FirstPersonMappingContext->MapKey(MoveAction, EKeys::D);
|
|
FirstPersonMappingContext->MapKey(LookAction, EKeys::Mouse2D);
|
|
FirstPersonMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftX);
|
|
FirstPersonMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftY);
|
|
FirstPersonMappingContext->MapKey(LookAction, EKeys::Gamepad_RightX);
|
|
FirstPersonMappingContext->MapKey(LookAction, EKeys::Gamepad_RightY);
|
|
|
|
TopDownMappingContext = NewObject<UInputMappingContext>(this, TEXT("IMC_Vocation_TP"));
|
|
TopDownMappingContext->MapKey(MoveAction, EKeys::W);
|
|
TopDownMappingContext->MapKey(MoveAction, EKeys::S);
|
|
TopDownMappingContext->MapKey(MoveAction, EKeys::A);
|
|
TopDownMappingContext->MapKey(MoveAction, EKeys::D);
|
|
TopDownMappingContext->MapKey(LookAction, EKeys::Mouse2D);
|
|
TopDownMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftX);
|
|
TopDownMappingContext->MapKey(MoveAction, EKeys::Gamepad_LeftY);
|
|
TopDownMappingContext->MapKey(LookAction, EKeys::Gamepad_RightX);
|
|
}
|
|
|
|
void AVocationPlayerController::ApplyLowGraphics()
|
|
{
|
|
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
|
{
|
|
GI->SetGraphicsPreset(EVocationGraphicsPreset::Low, false);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ApplyMediumGraphics()
|
|
{
|
|
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
|
{
|
|
GI->SetGraphicsPreset(EVocationGraphicsPreset::Medium, false);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ApplyHighGraphics()
|
|
{
|
|
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
|
{
|
|
GI->SetGraphicsPreset(EVocationGraphicsPreset::High, false);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ApplyUltraGraphics()
|
|
{
|
|
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
|
{
|
|
GI->SetGraphicsPreset(EVocationGraphicsPreset::Ultra, false);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::ApplyRayTracingGraphics()
|
|
{
|
|
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
|
{
|
|
GI->SetGraphicsPreset(EVocationGraphicsPreset::RayTracing, true);
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::JoinFirstFoundSession()
|
|
{
|
|
if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem<UVocationSessionSubsystem>())
|
|
{
|
|
Sessions->OnSessionSearchComplete.AddDynamic(this, &AVocationPlayerController::HandleSessionSearchForJoin);
|
|
Sessions->FindSessions();
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::HandleSessionSearchForJoin(const TArray<FString>& SessionNames)
|
|
{
|
|
if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem<UVocationSessionSubsystem>())
|
|
{
|
|
Sessions->OnSessionSearchComplete.RemoveDynamic(this, &AVocationPlayerController::HandleSessionSearchForJoin);
|
|
if (SessionNames.Num() > 0)
|
|
{
|
|
Sessions->JoinSessionByIndex(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AVocationPlayerController::QuickSave()
|
|
{
|
|
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
|
{
|
|
GI->SaveGame();
|
|
if (VocationHUD)
|
|
{
|
|
VocationHUD->ShowDebugStatus(TEXT("Game saved."));
|
|
}
|
|
}
|
|
}
|