// Project Lab - NHTV Igad #include "UnrealProject.h" #include "Runtime/Engine/Classes/Engine/LocalPlayer.h" #if PLATFORM_SPECIFIC_WIN == 0 // Include input manager for windows to allow DS4 controllers #include "InputManager.hpp" using namespace Input; #endif #include "DefaultGameInstance.h" #include "CharacterSettings.h" #include "Prefs.h" #include "PlayerControllerBase.h" #include "ScreenOverlay.h" #include "SessionManager.h" #include "ScreenOverlay.h" #include "MapData.h" #include "MapList.h" #include // Replicates the exact same data structure as FWindowsCursor except with a public cursor handle member #if PLATFORM_SPECIFIC_WIN == 0 class FWindowsCursor1 : public ICursor { public: EMouseCursor::Type CurrentType; HCURSOR CursorHandles[EMouseCursor::TotalCursorCount]; }; HCURSOR originalCursor; void InitWindowsCursors() { // Store original application cursor for editor FWindowsCursor1* windowsCursor = (FWindowsCursor1*)FSlateApplication::Get().GetPlatformCursor().Get(); originalCursor = windowsCursor->CursorHandles[EMouseCursor::Default]; } void ShutdownWindowsCursors() { // Reset original cursor, mainly for editor FWindowsCursor1* windowsCursor = (FWindowsCursor1*)FSlateApplication::Get().GetPlatformCursor().Get(); windowsCursor->CursorHandles[EMouseCursor::Default] = originalCursor; } HCURSOR LoadCustomCursor(const FString& path) { FString parentPath = FPaths::GameDir(); FString cursorPath = parentPath + "\\" + path; HCURSOR cursorHandle = LoadCursorFromFileW(*cursorPath); return cursorHandle; } void SetApplicationCursor(HCURSOR cursor) { FWindowsCursor1* windowsCursor = (FWindowsCursor1*)FSlateApplication::Get().GetPlatformCursor().Get(); if(windowsCursor) { HCURSOR handleDst; if(cursor != INVALID_HANDLE_VALUE) { handleDst = cursor; } else { handleDst = LoadCursor(GetModuleHandle(0), IDC_ARROW); } // Overwrite default cursor that unreal sets hack windowsCursor->CursorHandles[EMouseCursor::Default] = handleDst; } } #endif static UMapList* mapList; UDefaultGameInstance::UDefaultGameInstance() { mapList = ConstructorHelpers::FObjectFinder(TEXT("/Game/Assets/Levels/MapList")).Object; menuLevelPath = "/Game/Assets/Levels/Menu"; splashScreenShown = false; } void UDefaultGameInstance::Init() { m_characterSettings = nullptr; LoadSettings(); #if PLATFORM_SPECIFIC_WIN == 0 InitWindowsCursors(); SetApplicationCursor(LoadCustomCursor("cursor.cur")); #endif Super::Init(); m_prefs = nullptr; LoadPrefs(); m_LoadMaps(); #if PLATFORM_SPECIFIC_WIN == 0 // Initialize TEA Input Input::InputManager::Initialize(); Input::InputManager::GetInstance()->SearchForJoystick(); m_tickDelegateHandle = FTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateUObject(this, &UDefaultGameInstance::m_Tick), 0.016666667f); #endif m_localPlayer = nullptr; // Create session manager sessionManager = NewObject(this); sessionManager->m_instance = this; } bool UDefaultGameInstance::HandleOpenCommand(const TCHAR* Cmd, FOutputDevice& Ar, UWorld* InWorld) { GPRINT("Open command -> " + FString(Cmd) + " [" + InWorld->GetFullName() + "]"); APlayerControllerBase* pcb = Cast(GetFirstLocalPlayerController()); if(pcb && Super::HandleOpenCommand(Cmd, Ar, InWorld)) { FString msg = FString("Opening level [") + Cmd + "]"; pcb->overlay->ShowOverlay(msg); return true; } return false; } bool UDefaultGameInstance::m_Tick(float DeltaSeconds) { #if PLATFORM_SPECIFIC_WIN == 0 InputManager* inputManager = Input::InputManager::GetInstance(); inputManager->Update(); if(!inputManager->joystick) { std::vector names = inputManager->GetJoystickNames(); for(size_t i = 0; i < names.size(); i++) { inputManager->ConnectJoystickByIndex(i); if(inputManager->joystick) break; } } #endif return true; } void UDefaultGameInstance::Shutdown() { FTicker::GetCoreTicker().RemoveTicker(m_tickDelegateHandle); Super::Shutdown(); #if PLATFORM_SPECIFIC_WIN == 0 ShutdownWindowsCursors(); Input::InputManager::Cleanup(); #endif sessionManager->Shutdown(); } const FString levelPath = TEXT("/Game/Assets/Levels"); void UDefaultGameInstance::m_LoadMaps() { if (mapList) { for (int32 i = 0; i < mapList->mapList.Num(); i++) { UMapData* mapData = mapList->mapList[i]; FString name = mapData->GetName(); wchar_t* nameStrPtr = name.GetCharArray().GetData(); std::wstring nameStr = std::wstring(nameStrPtr, nameStrPtr + name.Len()); //GWPRINT(mapData->GetName() + L"\n" + mapData->GetPathName() + L"\n" + mapData->GetFullGroupName(false)); static std::wregex nameRx = std::wregex(L"I_([_a-zA-Z0-9]+)"); std::wsmatch match; if (std::regex_match(nameStr, match, nameRx)) { std::wstring levelNameStr = match[1]; FString matchingLevelName = FString(levelNameStr.c_str()); mapData->pathToAsset = levelPath + FString(L"/") + matchingLevelName + FString(L".") + matchingLevelName; mapData->pathToAsset = levelPath + FString(L"/") + matchingLevelName; //GWPRINT(L"Level asset path: " + mapData->pathToAsset); maps.Add(mapData); mapsByLevelName.Add(matchingLevelName, mapData); mapsByLevelPath.Add(mapData->pathToAsset, mapData); } else { GWERROR(L"Can't extract map name from level asset " + mapData->GetPathName()); } } } } ULocalPlayer* UDefaultGameInstance::CreateInitialPlayer(FString& OutError) { m_localPlayer = Super::CreateInitialPlayer(OutError); check(m_localPlayer); //m_localNetID = m_localPlayer->GetPreferredUniqueNetId(); //GWPRINT(L"Created local player " + m_localPlayer->GetName() + // ", NetID = " + m_localNetID->ToDebugString()); //check(m_localNetID.IsValid()); // Retrieve player name //IOnlineIdentityPtr identity = m_onlineSystem->GetIdentityInterface(); //playerID = identity->GetPlayerNickname(*m_localNetID); //GWPRINT(L"Assigned player ID: " + playerID); //IOnlineFriendsPtr friends = m_onlineSystem->GetFriendsInterface(); //if (friends.IsValid()) //{ // onReadFriendsListCompleteDelegate = FOnReadFriendsListComplete::CreateUObject(this, &UDefaultGameInstance::m_OnReadFriendsListCompleteDelegate); // friends->ReadFriendsList(0, TEXT("Friends"), onReadFriendsListCompleteDelegate); //} //ISteamFriends* steamFriends = steamIdentity->GetSteamFriendsPtr(); //steamIdentity //friends->GetLargeFriendAvatar() //ISteamUser* user; //FOnlineIdentitySteam* steam = (FOnlineIdentitySteam*)*identity; //class ISteamUser* steamUser = identity->Get return m_localPlayer; } void UDefaultGameInstance::OnSessionUserInviteAccepted(const bool bWasSuccess, const int32 ControllerId, TSharedPtr Us, const FOnlineSessionSearchResult& res) { sessionManager->AcceptUserInvite(bWasSuccess, ControllerId, Us, res); } void UDefaultGameInstance::SaveSettings() { if (m_characterSettings) { UCharacterSettings::Save(m_characterSettings); } } void UDefaultGameInstance::LoadSettings() { m_characterSettings = UCharacterSettings::Load(); } UCharacterSettings* UDefaultGameInstance::GetCharacterSettings() { return m_characterSettings; } void UDefaultGameInstance::SavePrefs() { if (m_prefs) { UPrefs::Save(m_prefs); } } void UDefaultGameInstance::LoadPrefs() { m_prefs = UPrefs::Load(); } UPrefs* UDefaultGameInstance::GetPrefs() { return m_prefs; } UMapData* UDefaultGameInstance::GetCurrentLevelMapData() { UWorld* world = GetWorld(); check(world); FString mapName = world->GetMapName(); FString name1 = world->GetName(); UMapData** res = mapsByLevelName.Find(name1); if (res) return *res; return nullptr; } class UMapData* UDefaultGameInstance::GetMapData(FString levelPath) { FString first; FString last; if(!levelPath.Split("/", &first, &last, ESearchCase::IgnoreCase, ESearchDir::FromEnd)) return nullptr; FString la, lb; if(last.Split(".", &la, &lb)) { last = lb; } levelPath = first + "/" + last; UMapData** res = mapsByLevelPath.Find(levelPath); if(res) return *res; return nullptr; } void UDefaultGameInstance::ShowNetworkError(const FString& msg) { APlayerControllerBase* controller = Cast(GetFirstLocalPlayerController()); check(controller); TArray options; options.Add("OK"); controller->overlay->ShowMessageBox("Network Error", msg, options); } int32 UDefaultGameInstance::GetScalabilityQuality() { const Scalability::FQualityLevels current = GEngine->GetGameUserSettings()->ScalabilityQuality; // Check if any we know Scalability::FQualityLevels setting; for (int32 i = 0; i < 4; i++) { setting.SetFromSingleQualityLevel(i); if (current == setting) return i; } // Custom return -1; } void UDefaultGameInstance::SetScalabilityQuality(int32 scalability) { GEngine->GetGameUserSettings()->ScalabilityQuality.SetFromSingleQualityLevel(scalability); GEngine->GetGameUserSettings()->ApplySettings(false); GEngine->GetGameUserSettings()->SaveSettings(); m_prefs->usingCustomGraphicsSettings = false; SavePrefs(); //if (GConfig) //{ // GConfig->SetInt( // TEXT("ScalabilityGroups"), // TEXT("sg.Preset"), // scalability, // GGameUserSettingsIni); // GConfig->Flush(false, GGameUserSettingsIni); //} } static int32 GenerateResolutionQuality(int32 value) { Scalability::FQualityLevels setting; setting.SetFromSingleQualityLevel(value); return setting.ResolutionQuality; } static int32 RevertResolutionQuality(int32 value) { Scalability::FQualityLevels setting; for (int32 i = 0; i < 4; i++) { setting.SetFromSingleQualityLevel(i); if (setting.ResolutionQuality == value) return i; } return 0; } void UDefaultGameInstance::SetScalabilityQualityValues(int32 ResolutionQuality, int32 AntiAliasingQuality, int32 ShadowQuality, int32 PostProcessQuality, int32 TextureQuality, int32 EffectsQuality) { Scalability::FQualityLevels setting; setting.SetFromSingleQualityLevel(ResolutionQuality); setting.AntiAliasingQuality = AntiAliasingQuality; setting.ShadowQuality = ShadowQuality; setting.PostProcessQuality = PostProcessQuality; setting.TextureQuality = TextureQuality; setting.EffectsQuality = EffectsQuality; setting.ViewDistanceQuality = TextureQuality; GEngine->GetGameUserSettings()->ScalabilityQuality = setting; GEngine->GetGameUserSettings()->ApplySettings(false); GEngine->GetGameUserSettings()->SaveSettings(); m_prefs->usingCustomGraphicsSettings = true; m_prefs->customGraphicsSettings[0] = ResolutionQuality; m_prefs->customGraphicsSettings[1] = AntiAliasingQuality; m_prefs->customGraphicsSettings[2] = ShadowQuality; m_prefs->customGraphicsSettings[3] = PostProcessQuality; m_prefs->customGraphicsSettings[4] = TextureQuality; m_prefs->customGraphicsSettings[5] = EffectsQuality; SavePrefs(); } int32 UDefaultGameInstance::GetScalabilityQualityValue(EGraphicsSetting setting) { const Scalability::FQualityLevels current = GEngine->GetGameUserSettings()->ScalabilityQuality; switch (int32(setting)) { case 0: return RevertResolutionQuality(current.ResolutionQuality); case 1: return current.AntiAliasingQuality; case 2: return current.ShadowQuality; case 3: return current.PostProcessQuality; case 4: return current.TextureQuality; case 5: return current.EffectsQuality; } return 0; } void UDefaultGameInstance::SetScalabilityQualityValue(EGraphicsSetting setting, int32 value) { if (int32(setting) >= 6) return; Scalability::FQualityLevels current = GEngine->GetGameUserSettings()->ScalabilityQuality; switch (int32(setting)) { case 0: current.ResolutionQuality = GenerateResolutionQuality(value); break; case 1: current.AntiAliasingQuality = value; break; case 2: current.ShadowQuality = value; break; case 3: current.PostProcessQuality = value; break; case 4: current.TextureQuality = value; break; case 5: current.EffectsQuality = value; break; } GEngine->GetGameUserSettings()->ScalabilityQuality = current; GEngine->GetGameUserSettings()->ApplySettings(false); GEngine->GetGameUserSettings()->SaveSettings(); m_prefs->usingCustomGraphicsSettings = true; m_prefs->customGraphicsSettings[int32(setting)] = value; SavePrefs(); } void UDefaultGameInstance::SetupLoadingScreen() { m_loadingScreen.bAutoCompleteWhenLoadingCompletes = true; m_loadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget(); // <-- test screen that comes with m_loadingScreen.MinimumLoadingScreenDisplayTime = 1.0f; GetMoviePlayer()->SetupLoadingScreen(m_loadingScreen); } /* void UDefaultGameInstance::OnSessionUserInviteAccepted(const bool bWasSuccess, const int32 ControllerId, TSharedPtr< const FUniqueNetId > Us, const FOnlineSessionSearchResult& res) { if (bWasSuccess) { m_JoinOnlineSession(res); } else { GWWARNING(L"OnSessionUserInviteAccepted was not successful"); } } void UDefaultGameInstance::m_OnCreateSessionComplete(FName sessionName, bool successful) { JWPRINT(L"OnCreateSessionComplete " + sessionName.ToString().GetCharArray().GetData() + L", " + successful); m_session->ClearOnCreateSessionCompleteDelegate_Handle(onCreateSessionCompleteDelegateHandle); if (successful) { //onStartSessionCompleteDelegateHandle = m_session->AddOnStartSessionCompleteDelegate_Handle(onStartSessionCompleteDelegate); //m_session->StartSession(sessionName); FString options = FString("listen"); // Add additional game settings here options += FString("?teamCount=") + FString::FromInt(hostMaxTeamCount); SetupLoadingScreen(); UGameplayStatics::OpenLevel(GetWorld(), FName(hostLoadMap.GetCharArray().GetData()), true, options); } else { ShowNetworkError("Failed to create session"); } } void UDefaultGameInstance::m_OnStartOnlineGameComplete(FName sessionName, bool successful) { JWPRINT(L"OnStartOnlineGameComplete " + sessionName.ToString().GetCharArray().GetData() + L", " + successful); m_session->ClearOnStartSessionCompleteDelegate_Handle(onStartSessionCompleteDelegateHandle); if (successful) { FString options = FString("listen"); // Add additional game settings here options += FString("?teamCount=") + FString::FromInt(hostMaxTeamCount); SetupLoadingScreen(); UGameplayStatics::OpenLevel(GetWorld(), FName(hostLoadMap.GetCharArray().GetData()), true, options); } else { ShowNetworkError("Failed to start session"); } } void UDefaultGameInstance::m_OnFindSessionsComplete(bool successful) //__attribute__((optnone)) { JWPRINT(L"OnFindSessionsComplete " + successful); m_operationInProgress = false; if(m_findingOverlay) { m_findingOverlay->Close(); m_findingOverlay = nullptr; } m_session->ClearOnFindSessionsCompleteDelegate_Handle(onFindSessionsCompleteDelegateHandle); JPRINT("OnFindSessionsComplete: " + sessionSearch->SearchResults.Num() + " sessions"); if (sessionSearch->SearchResults.Num() > 0) { for (int32 SearchIdx = 0; SearchIdx < sessionSearch->SearchResults.Num(); SearchIdx++) { JWPRINT(SearchIdx + L", " + sessionSearch->SearchResults[SearchIdx].Session.OwningUserName); } } } void UDefaultGameInstance::m_OnJoinSessionComplete(FName sessionName, EOnJoinSessionCompleteResult::Type result) { JWPRINT(L"OnStartOnlineGameComplete " + sessionName.ToString().GetCharArray().GetData() + L", " + int32(result)); m_session->ClearOnJoinSessionCompleteDelegate_Handle(onJoinSessionCompleteDelegateHandle); m_operationInProgress = false; if(result != EOnJoinSessionCompleteResult::Success) { ShowNetworkError(FString("Failed to join session, Error Code ") + FString::FromInt(result)); SetGameJoined(); return; } APlayerController* const playerController = GetFirstLocalPlayerController(); check(playerController); SetupLoadingScreen(); playerController->ClientTravel(m_travelURL, ETravelType::TRAVEL_Absolute); } void UDefaultGameInstance::m_OnDestroySessionComplete(FName sessionName, bool successful) { JWPRINT(L"OnDestroySessionComplete " + sessionName.ToString().GetCharArray().GetData() + L", " + successful); m_session->ClearOnDestroySessionCompleteDelegate_Handle(onDestroySessionCompleteDelegateHandle); if(m_travelOnSessionDestroy) { UGameplayStatics::OpenLevel(GetWorld(), "/Game/Assets/Levels/Menu", true); } } void UDefaultGameInstance::m_OnReadFriendsListCompleteDelegate(int32, bool, const FString&, const FString&) { GPRINT("Got friends list"); } */