// 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(TEXT("/Game/Assets/GUI/WEEGEE_Overlay")).Class; transitionWidgetClass = ConstructorHelpers::FClassFinder(TEXT("/Game/Assets/GUI/WEEGEE_Transition")).Class; } void APlayerControllerBase::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(APlayerControllerBase, setupState); } void APlayerControllerBase::BeginPlay() { UDefaultGameInstance* game = Cast(GetGameInstance()); if(IsLocalController()) { transitionScreen = CreateWidget(GetWorld(), transitionWidgetClass); transitionScreen->AddToViewport(800); overlay = CreateWidget(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(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 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(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; } }