// Project Lab - NHTV Igad #include "UnrealProject.h" #include "LobbyMenu.h" #include "LobbySlot.h" #include "DefaultPlayer.h" #include "PlayerStateBase.h" #include "MenuController.h" #include "DefaultGameInstance.h" #include "MenuGameMode.h" #include "GameStateBase.h" #include "SubMenu.h" #include "SessionManager.h" #include "Engine.h" #include "ScreenOverlay.h" #include "CharacterSettings.h" ULobbyMenu::ULobbyMenu(const FObjectInitializer& init) : Super(init) { } void ULobbyMenu::NativeConstruct() { m_teamContainer = Cast(WidgetTree->FindWidget("Container")); Super::NativeConstruct(); } void ULobbyMenu::NativeDestruct() { Super::NativeDestruct(); } void ULobbyMenu::NativeTick(const FGeometry& MyGeometry, float InDeltaTime) { Super::NativeTick(MyGeometry, InDeltaTime); if(!m_myState) { // Try to aquire my local player state, this is in Tick because player states are not guaranteed during BeginPlay UWorld* const world = GetWorld(); check(world); APlayerControllerBase* player = Cast(world->GetGameInstance()->GetFirstLocalPlayerController()); check(player); m_myState = Cast(player->PlayerState); } UWorld* world = GetWorld(); check(world); AGameStateBase* gameState = Cast(world->GetGameState()); check(gameState); TArray teamSizes = gameState->GetTeamSizes(); TArray> playersPerTeam = gameState->GetPlayersByTeam(); // Update team slots with their respective player arrays for (int32 i = 0; i < (int32)m_numTeams; i++) { if((i + 1) < playersPerTeam.Num()) { m_lobbySlots[i]->UpdatePlayers(playersPerTeam[i+1]); } else m_lobbySlots[i]->UpdatePlayers(TArray()); if (i > teamSizes.Num()) { m_lobbySlots[i]->SetState(false); } else { m_lobbySlots[i]->SetState(true); } } } void ULobbyMenu::Init() { // Generate the selectable builds UWorld* world = GetWorld(); check(world); UDefaultGameInstance* instance = Cast(world->GetGameInstance()); check(instance); UCharacterSettings* settings = instance->GetCharacterSettings(); check(settings); m_characters = settings->characterSaves; // Remove existing lobby slots for(ULobbySlot* s : m_lobbySlots) { s->RemoveFromParent(); } m_lobbySlots.SetNum(0); if(!m_teamContainer) { GWERROR("Container not set, can't initialize lobby menu"); return; } UPanelWidget* panel = Cast(m_teamContainer->WidgetTree->RootWidget); if (!panel) { GWERROR(L"No UPanelWidget found"); return; } // Create team slots in this menu for the amount of selected teams in the game setup screen AGameStateBase* gameState = Cast(world->GetGameState()); check(gameState); m_numTeams = gameState->GetMapTeamCount(); for (uint32 i = 0; i < m_numTeams; i++) { ULobbySlot* slot = CreateWidget(GetWorld(), lobbySlotClass); check(slot); panel->AddChild(slot); slot->SetTeamIndex(i+1); m_lobbySlots.Add(slot); } m_teamContainer->RescanItems(); } void ULobbyMenu::ToggleReadyState() { // Toggle my player state's ready state if(!m_myState) { UWorld* const world = GetWorld(); check(world); APlayerControllerBase* player = Cast(world->GetGameInstance()->GetFirstLocalPlayerController()); check(player); m_myState = Cast(player->PlayerState); } if(m_myState) m_myState->SetReadyState(!m_myState->GetReadyState()); } void ULobbyMenu::StartGame() { UWorld* world = GetWorld(); check(world); AGameStateBase* gameState = Cast(world->GetGameState()); check(gameState); TArray players = gameState->GetPlayers(); // Check if we're the host AMenuGameMode* gameMode = world->GetAuthGameMode(); if(gameMode) { // Check if everyone's ready for (size_t i = 0; i < players.Num(); i++) { if (!players[i]->GetReadyState()) return; } // Tell the game to start GPRINT("Starting game"); if(!gameMode->StartGame()) { GERROR("Failed to start game"); TArray options; options.Add("OK"); Cast(GetOwningPlayer())->overlay->ShowMessageBox("Error", "Failed to start game", options); } } } void ULobbyMenu::GotoTeamSelector() { if (m_teamContainer) { OpenSubMenu(m_teamContainer); } } void ULobbyMenu::BackToMenu() { // Close active session UDefaultGameInstance* inst = Cast(GetOwningPlayer()->GetGameInstance()); inst->sessionManager->DestroySession(); inst->sessionManager->CloseNetConnections(); // Goto menu AMenuController* mc = Cast(GetOwningPlayer()); mc->SwitchToMenu(); } bool ULobbyMenu::IsHost() const { if (!GetOwningPlayer()) return false; return GetOwningPlayer()->Role == ROLE_Authority; } void ULobbyMenu::OnLobbyEnter() { // Register session callbacks UDefaultGameInstance* inst = Cast(GetOwningPlayer()->GetGameInstance()); Init(); } TArray ULobbyMenu::GetCharacterSaves() { return m_characters; }