557 lines
16 KiB
C++
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");
|
|
}
|
|
*/ |