204 lines
5.2 KiB
C++
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;
|
|
} |