// Project Lab - NHTV Igad #include "UnrealProject.h" #include "MapData.h" #include "MapSelectionScreen.h" #include "AssetRegistryModule.h" #include "DefaultGameInstance.h" #include "MapSlot.h" #include "SessionManager.h" #include "MenuController.h" #include "ScreenOverlay.h" #include "MenuGameMode.h" static UClass* mapSlotWidgetClass; UMapSelectionScreen::UMapSelectionScreen(const FObjectInitializer& init) : Super(init) { mapSlotWidgetClass = ConstructorHelpers::FClassFinder(TEXT("/Game/Assets/GUI/Components/WEEGEE_MapListItem")).Class; } void UMapSelectionScreen::NativeConstruct() { Super::NativeConstruct(); if(container) { // Get all the available maps and create selection buttons for them UWorld* world = GetWorld(); check(world); auto& maps = Cast(world->GetGameInstance())->maps; for(int32 i = 0; i < maps.Num(); i++) { UMapSlot* mapSlot = CreateWidget(GetWorld(), mapSlotWidgetClass); check(mapSlot); mapSlot->mapData = maps[i]; mapSlot->mapScreen = this; mapSlot->OnMapSet(); m_mapSlots.Add(mapSlot); container->AddChild(mapSlot); } onItemSelected.RemoveAll(this); onItemSelected.AddDynamic(this, &UMapSelectionScreen::OnSelectionChanged); RescanItems(); SelectMap(0); } } void UMapSelectionScreen::OnSelectionChanged(UMenuItemBase* item) { UMapSlot* mapSlot = Cast(item); if(mapSlot) { //SelectMap(mapSlot->index); } } void UMapSelectionScreen::SelectMap(int32 index) { UWorld* world = GetWorld(); check(world); UDefaultGameInstance* inst = Cast(world->GetGameInstance()); TArray& maps = inst->maps; if(index < 0 || index > maps.Num()) { GWERROR(L"Selected map out of range"); return; } mapData = maps[index]; check(mapData); // Set the asset path to the selected map in the session manager AMenuGameMode* gameMode = Cast(world->GetAuthGameMode()); if(gameMode) { gameMode->SetMap(mapData->pathToAsset); GWPRINT(L"Selected map: " + maps[index]->friendlyName); } else { GWARNING(L"Can't select map, no game mode!"); } } void UMapSelectionScreen::CreateGame() { SelectMap(GetSelectedItem()); if(!mapData) { GERROR("No map set"); return; } UWorld* world = GetWorld(); check(world); UDefaultGameInstance* inst = Cast(world->GetGameInstance()); AMenuGameMode* gameMode = Cast(world->GetAuthGameMode()); if(!gameMode) { GERROR("Can't start game, no menu game mode set"); return; } APlayerControllerBase* pc = Cast(GetOwningPlayer()); if(m_sessionCreateOverlay) return; // Already creating session m_sessionCreateOverlay = pc->overlay->ShowOverlay("Creating session"); // Set the map setting in the game mode gameMode->AssignMapData(mapData); // Make sure there is no connection already inst->sessionManager->CloseNetConnections(); // Set host settings FOnlineSessionSettings& sessionSettings = inst->sessionManager->sessionSettings; sessionSettings.NumPublicConnections = mapData->maxTeamCount * 2; // Team count setting translated to max connected players (x2) sessionSettings.Set(SETTING_MAPNAME, mapData->pathToAsset, EOnlineDataAdvertisementType::ViaOnlineServiceAndPing); // Create a new session inst->sessionManager->onCreateSessionComplete.AddUObject(this, &UMapSelectionScreen::m_OnCreateSessionCompleted); inst->sessionManager->CreateSession(); } void UMapSelectionScreen::m_OnCreateSessionCompleted(bool success) { if(m_sessionCreateOverlay) { m_sessionCreateOverlay->Close(); m_sessionCreateOverlay = nullptr; } UDefaultGameInstance* inst = Cast(GetWorld()->GetGameInstance()); inst->sessionManager->onCreateSessionComplete.RemoveAll(this); AMenuController* mc = Cast(GetOwningPlayer()); if(success) { // Goto the lobby mc->OnEnterLobby(); // Start the session, @note not sure if this is needed //inst->sessionManager->StartSession(); } else { TArray options; options.Add("OK"); mc->overlay->ShowMessageBox("Error", "Failed to create game session", options); } } UMapData::UMapData() { maxTeamCount = 3; friendlyName = "Map Name"; description = ""; }