haxis/Source/UnrealProject/GameState/DefaultGameInstance.cpp

557 lines
16 KiB
C++

// 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 <regex>
// 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<UMapList>(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<USessionManager>(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<APlayerControllerBase>(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<std::wstring> 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<const FUniqueNetId> 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<APlayerControllerBase>(GetFirstLocalPlayerController());
check(controller);
TArray<FString> 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");
}
*/