haxis/Source/UnrealProject/GameState/PlayerControllerBase.cpp

398 lines
14 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "DefaultGameInstance.h"
#include "PlayerControllerBase.h"
#include "ScreenOverlay.h"
#include "Prefs.h"
#include "TransitionScreen.h"
#include "SessionManager.h"
#include "Engine.h"
#if PLATFORM_SPECIFIC_WIN == 0
#include "InputManager.hpp"
using namespace Input;
#endif
UClass* overlayWidgetClass;
UClass* transitionWidgetClass;
APlayerControllerBase::APlayerControllerBase(const FObjectInitializer& init)
: Super(init)
{
overlayWidgetClass = ConstructorHelpers::FClassFinder<UScreenOverlay>(TEXT("/Game/Assets/GUI/WEEGEE_Overlay")).Class;
transitionWidgetClass = ConstructorHelpers::FClassFinder<UTransitionScreen>(TEXT("/Game/Assets/GUI/WEEGEE_Transition")).Class;
}
void APlayerControllerBase::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(APlayerControllerBase, setupState);
}
void APlayerControllerBase::BeginPlay()
{
UDefaultGameInstance* game = Cast<UDefaultGameInstance>(GetGameInstance());
if(IsLocalController())
{
transitionScreen = CreateWidget<UTransitionScreen>(GetWorld(), transitionWidgetClass);
transitionScreen->AddToViewport(800);
overlay = CreateWidget<UScreenOverlay>(GetWorld(), overlayWidgetClass);
overlay->AddToViewport(1000);
AddMenuInputItem(overlay, 10);
check(overlay);
UWorld* world = GetWorld();
AGameMode* gameMode = nullptr;
if(world)
gameMode = GetWorld()->GetAuthGameMode();
//if(!game->errorMessage.IsEmpty())
//{
// game->DestroySession(false);
// game->ShowNetworkError(FString("Disconnected from game, ") + game->errorMessage);
// game->errorMessage.Empty();
//}
//else if(gameMode && UGameplayStatics::HasOption(gameMode->OptionsString, "closed"))
//{
// game->DestroySession(false);
// game->ShowNetworkError(FString("Disconnected from game"));
//}
}
Super::BeginPlay();
}
void APlayerControllerBase::SetupInputComponent()
{
if (GetWorld()->WorldType == EWorldType::Preview)
return;
Super::SetupInputComponent();
#if PLATFORM_SPECIFIC_WIN == 0
GPRINT("Binding Menu Input manager bindings on " + GetName());
InputManager* inputManager = InputManager::GetInstance();
UPrefs* prefs = Cast<UDefaultGameInstance>(GetGameInstance())->GetPrefs();
// Connect initial controller
inputManager->SearchForJoystick();
ScanForJoysticks();
int32 connect = 0;
for(int32 i = 0; i < m_recentJoystickScan.Num(); i++)
{
if(m_recentJoystickScan[i] == prefs->useControllerName)
{
connect = i;
break;
}
}
SelectJoystick(connect);
inputManager->RegisterCallback(IJP_FACEDOWN, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuConfirm);
inputManager->RegisterCallback(IJP_FACERIGHT,IME_PRESSED, this, &APlayerControllerBase::m_OnMenuBack);
inputManager->RegisterCallback(IJP_START, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuStart);
inputManager->RegisterCallback(IJP_DPADUP, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuUp);
inputManager->RegisterCallback(IJP_DPADDOWN, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuDown);
inputManager->RegisterCallback(IJP_DPADLEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuLeft);
inputManager->RegisterCallback(IJP_DPADRIGHT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuRight);
inputManager->RegisterCallback(IJP_TRIGGERLEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuLeftPressed);
inputManager->RegisterCallback(IJP_TRIGGERRIGHT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuRightPressed);
inputManager->RegisterCallback(IJP_TRIGGERLEFT, IME_RELEASED, this, &APlayerControllerBase::m_OnMenuLeftReleased);
inputManager->RegisterCallback(IJP_TRIGGERRIGHT, IME_RELEASED, this, &APlayerControllerBase::m_OnMenuRightReleased);
inputManager->RegisterCallback(IJP_SHOULDERLEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuShoulderLeft);
inputManager->RegisterCallback(IJP_SHOULDERRIGHT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuShoulderRight);
inputManager->RegisterCallback(IJP_START, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuOptionsButton);
inputManager->RegisterCallback(IJP_FACELEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuOpt1);
inputManager->RegisterCallback(IJP_FACEUP, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuOpt2);
#endif
InputComponent->BindAction("MenuSelect", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuConfirm);
InputComponent->BindAction("MenuBack", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuBack);
InputComponent->BindAction("MenuStart", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuStart);
InputComponent->BindAction("MenuUp", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuUp);
InputComponent->BindAction("MenuDown", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuDown);
InputComponent->BindAction("MenuLeft", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuLeftPressed);
InputComponent->BindAction("MenuRight", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuRightPressed);
InputComponent->BindAction("MenuLeftUp", EInputEvent::IE_Released, this, &APlayerControllerBase::m_OnMenuLeftReleased);
InputComponent->BindAction("MenuRightUp", EInputEvent::IE_Released, this, &APlayerControllerBase::m_OnMenuRightReleased);
InputComponent->BindAction("MenuOpt1", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuOpt1);
InputComponent->BindAction("MenuOpt2", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuOpt2);
InputComponent->BindAction("MenuShoulderLeft", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuShoulderLeft);
InputComponent->BindAction("MenuShoulderRight", EInputEvent::IE_Pressed, this, &APlayerControllerBase::m_OnMenuShoulderRight);
}
void APlayerControllerBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if(IsLocalController())
{
if(transitionScreen)
{
transitionScreen->OnHide();
transitionScreen->RemoveFromViewport();
}
if(overlay)
{
overlay->RemoveFromViewport();
}
}
Super::EndPlay(EndPlayReason);
}
void APlayerControllerBase::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
if(m_repeatLeft)
OnMenuAction(EMenuActionBinding::Repeat_Left);
if(m_repeatRight)
OnMenuAction(EMenuActionBinding::Repeat_Right);
}
void APlayerControllerBase::Destroyed()
{
Super::Destroyed();
#if PLATFORM_SPECIFIC_WIN == 0
GPRINT("Unbinding Menu Input manager bindings on " + GetName());
InputManager* inputManager = InputManager::GetInstance();
inputManager->DeregisterCallback(IJP_FACEDOWN, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuConfirm);
inputManager->DeregisterCallback(IJP_FACERIGHT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuBack);
inputManager->DeregisterCallback(IJP_START, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuStart);
inputManager->DeregisterCallback(IJP_DPADUP, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuUp);
inputManager->DeregisterCallback(IJP_DPADDOWN, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuDown);
inputManager->DeregisterCallback(IJP_DPADLEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuLeft);
inputManager->DeregisterCallback(IJP_DPADRIGHT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuRight);
inputManager->DeregisterCallback(IJP_TRIGGERLEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuLeftPressed);
inputManager->DeregisterCallback(IJP_TRIGGERRIGHT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuRightPressed);
inputManager->DeregisterCallback(IJP_TRIGGERLEFT, IME_RELEASED, this, &APlayerControllerBase::m_OnMenuLeftReleased);
inputManager->DeregisterCallback(IJP_TRIGGERRIGHT, IME_RELEASED, this, &APlayerControllerBase::m_OnMenuRightReleased);
inputManager->DeregisterCallback(IJP_SHOULDERLEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuShoulderLeft);
inputManager->DeregisterCallback(IJP_SHOULDERRIGHT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuShoulderRight);
inputManager->DeregisterCallback(IJP_START, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuOptionsButton);
inputManager->DeregisterCallback(IJP_FACELEFT, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuOpt1);
inputManager->DeregisterCallback(IJP_FACEUP, IME_PRESSED, this, &APlayerControllerBase::m_OnMenuOpt2);
#endif
}
void APlayerControllerBase::OnLearnSkill(class UBaseSkillObject* object)
{
}
void APlayerControllerBase::OnUnlearnSkill(class UBaseSkillObject* object)
{
}
void APlayerControllerBase::AddMenuInputItem(class UMenuItemBase* item, int32 priority)
{
if(!item)
return;
if(m_menuItemStack.Contains(item))
return;
item->priority = priority;
int32 at = m_menuItemStack.Num();
if(at == -1)
{
m_menuItemStack.Add(item);
return;
}
while(at > 0 && m_menuItemStack[at-1]->priority > priority)
{
at--;
}
m_menuItemStack.Insert(item, at);
}
void APlayerControllerBase::RemoveMenuInputItem(class UMenuItemBase* item)
{
m_menuItemStack.Remove(item);
}
EInputMethod APlayerControllerBase::GetInputMethod() const
{
#if PLATFORM_SPECIFIC_WIN == 0
InputManager* inputManager = InputManager::GetInstance();
switch(inputManager->GetConnectedType())
{
default:
case InputDeviceType::IDT_NONE:
case InputDeviceType::IDT_NOTDEFINED:
return EInputMethod::PC;
break;
case InputDeviceType::IDT_XBOX:
return EInputMethod::X360;
break;
case InputDeviceType::IDT_DS4:
return EInputMethod::DS4;
break;
}
#else
return EInputMethod::DS4;
#endif
}
TArray<FString> APlayerControllerBase::ScanForJoysticks()
{
#if PLATFORM_SPECIFIC_WIN == 0
m_recentJoystickScan.SetNum(0);
InputManager* inputManager = InputManager::GetInstance();
inputManager->SearchForJoystick();
for(std::wstring s : inputManager->GetJoystickNames())
{
m_recentJoystickScan.Add(FString(s.c_str()));
}
#endif
return m_recentJoystickScan;
}
void APlayerControllerBase::SelectJoystick(int32 joystick)
{
#if PLATFORM_SPECIFIC_WIN == 0
if(joystick >= m_recentJoystickScan.Num())
return;
InputManager* inputManager = InputManager::GetInstance();
GWPRINT(L"Connecting joystick [" + joystick + L"] " + m_recentJoystickScan[joystick]);
inputManager->ConnectJoystickByIndex(joystick);
#endif
}
void APlayerControllerBase::PreClientTravel(const FString& PendingURL, ETravelType TravelType, bool bIsSeamlessTravel)
{
GPRINT("PRE TRAVEL: " + PendingURL);
Super::PreClientTravel(PendingURL, TravelType, bIsSeamlessTravel);
}
void APlayerControllerBase::OnEnterLobby()
{
GWARNING("PC: Entering lobby " + GetName());
}
void APlayerControllerBase::ReturnToMenu()
{
GWARNING("PC: Leaving game " + GetName());
UDefaultGameInstance* inst = Cast<UDefaultGameInstance>(GetGameInstance());
inst->sessionManager->DestroySession();
inst->sessionManager->CloseNetConnections();
// Load menu level
//FString error;
//FWorldContext* worldContext = GEngine->GetWorldContextFromWorld(GetWorld());
//FURL target = FURL(*inst->menuLevelPath);
//int32 ret = GEngine->Browse(*worldContext, target, error);
//if(ret == EBrowseReturnVal::Failure)
//{
// GERROR("Failed to load menu level: " + error);
//}
GetWorld()->ServerTravel(inst->menuLevelPath, true);
}
void APlayerControllerBase::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
GPRINT("[" + GetName() + "]Got player state");
}
void APlayerControllerBase::OnRep_Pawn()
{
Super::OnRep_Pawn();
if(GetPawn())
{
GPRINT("[" + GetName() + "]Got pawn: " + GetPawn()->GetName());
}
else
{
GPRINT("[" + GetName() + "]Unpossessed pawn");
}
}
void APlayerControllerBase::EnterLobby_Implementation()
{
OnEnterLobby();
}
void APlayerControllerBase::OnRep_Setup()
{
GPRINT("GOT SETUP STATE ON " + GetName());
m_onSetupStateSet = true;
}
void APlayerControllerBase::m_OnMenuConfirm()
{
OnMenuAction(EMenuActionBinding::Confirm);
}
void APlayerControllerBase::m_OnMenuBack()
{
OnMenuAction(EMenuActionBinding::Back);
}
void APlayerControllerBase::m_OnMenuStart()
{
OnMenuAction(EMenuActionBinding::Start);
}
void APlayerControllerBase::m_OnMenuUp()
{
OnMenuAction(EMenuActionBinding::Up);
}
void APlayerControllerBase::m_OnMenuDown()
{
OnMenuAction(EMenuActionBinding::Down);
}
void APlayerControllerBase::m_OnMenuLeft()
{
OnMenuAction(EMenuActionBinding::Left);
}
void APlayerControllerBase::m_OnMenuRight()
{
OnMenuAction(EMenuActionBinding::Right);
}
void APlayerControllerBase::m_OnMenuOpt1()
{
OnMenuAction(EMenuActionBinding::Opt1);
}
void APlayerControllerBase::m_OnMenuOpt2()
{
OnMenuAction(EMenuActionBinding::Opt2);
}
void APlayerControllerBase::m_OnMenuLeftPressed()
{
m_repeatLeft = true;
m_OnMenuLeft();
OnMenuAction(EMenuActionBinding::Repeat_Left);
OnMenuAction(EMenuActionBinding::Trigger_Left);
}
void APlayerControllerBase::m_OnMenuRightPressed()
{
m_repeatRight = true;
m_OnMenuRight();
OnMenuAction(EMenuActionBinding::Repeat_Right);
OnMenuAction(EMenuActionBinding::Trigger_Right);
}
void APlayerControllerBase::m_OnMenuLeftReleased()
{
m_repeatLeft = false;
}
void APlayerControllerBase::m_OnMenuRightReleased()
{
m_repeatRight = false;
}
void APlayerControllerBase::m_OnMenuShoulderLeft()
{
OnMenuAction(EMenuActionBinding::Shoulder_Left);
}
void APlayerControllerBase::m_OnMenuShoulderRight()
{
OnMenuAction(EMenuActionBinding::Shoulder_Right);
}
void APlayerControllerBase::m_OnMenuOptionsButton()
{
OnMenuAction(EMenuActionBinding::Options);
}
void APlayerControllerBase::OnMenuAction(EMenuActionBinding action)
{
m_menuItemStack.Remove(nullptr);
for(int32 i = m_menuItemStack.Num(); i > 0;)
{
i--;
m_menuItemStack[i]->NativeOnMenuAction(action);
if(m_menuItemStack[i]->blockInput)
break;
}
}