haxis/Source/UnrealProject/GUI/Lobby/LobbyMenu.cpp

204 lines
5.2 KiB
C++

// 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<USubMenu>(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<APlayerControllerBase>(world->GetGameInstance()->GetFirstLocalPlayerController());
check(player);
m_myState = Cast<APlayerStateBase>(player->PlayerState);
}
UWorld* world = GetWorld();
check(world);
AGameStateBase* gameState = Cast<AGameStateBase>(world->GetGameState());
check(gameState);
TArray<int32> teamSizes = gameState->GetTeamSizes();
TArray<TArray<APlayerStateBase*>> 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<APlayerStateBase*>());
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<UDefaultGameInstance>(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<UPanelWidget>(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<AGameStateBase>(world->GetGameState());
check(gameState);
m_numTeams = gameState->GetMapTeamCount();
for (uint32 i = 0; i < m_numTeams; i++)
{
ULobbySlot* slot = CreateWidget<ULobbySlot>(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<APlayerControllerBase>(world->GetGameInstance()->GetFirstLocalPlayerController());
check(player);
m_myState = Cast<APlayerStateBase>(player->PlayerState);
}
if(m_myState)
m_myState->SetReadyState(!m_myState->GetReadyState());
}
void ULobbyMenu::StartGame()
{
UWorld* world = GetWorld();
check(world);
AGameStateBase* gameState = Cast<AGameStateBase>(world->GetGameState());
check(gameState);
TArray<APlayerStateBase*> players = gameState->GetPlayers<APlayerStateBase>();
// Check if we're the host
AMenuGameMode* gameMode = world->GetAuthGameMode<AMenuGameMode>();
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<FString> options;
options.Add("OK");
Cast<APlayerControllerBase>(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<UDefaultGameInstance>(GetOwningPlayer()->GetGameInstance());
inst->sessionManager->DestroySession();
inst->sessionManager->CloseNetConnections();
// Goto menu
AMenuController* mc = Cast<AMenuController>(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<UDefaultGameInstance>(GetOwningPlayer()->GetGameInstance());
Init();
}
TArray<FCharacterSave> ULobbyMenu::GetCharacterSaves()
{
return m_characters;
}