haxis/Source/UnrealProject/GameState/KingOfTheHillGameMode.cpp

131 lines
3.5 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "KingOfTheHillGameMode.h"
#include "DefaultGameState.h"
#include "DefaultGameState.h"
#include "DefaultGameInstance.h"
#include "PlayerSpawn.h"
#include "NetworkPlayer.h"
#include "CreatureSpawn.h"
#include "DefaultPlayer.h"
#include "DefaultPlayerState.h"
#include "KOTHPlayerController.h"
#include "KOTHGameState.h"
#include "KOTHBossSpawner.h"
AKingOfTheHillGameMode::AKingOfTheHillGameMode()
{
PrimaryActorTick.bCanEverTick = true;
// Lobby system starts the match
bDelayedStart = true;
PlayerControllerClass = AKOTHPlayerController::StaticClass();
DefaultPawnClass = ConstructorHelpers::FClassFinder<APawn>(TEXT("/Game/Assets/Blueprints/BP_DefaultPlayer")).Class;
SpectatorClass = ConstructorHelpers::FClassFinder<ASpectatorPawn>(TEXT("/Game/Assets/Blueprints/BP_SpectatorPawn")).Class;
GameStateClass = AKOTHGameState::StaticClass();
PlayerStateClass = ADefaultPlayerState::StaticClass();
maxGameScore = 60.0f;
m_currentTeamWithHill = -1;
}
void AKingOfTheHillGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
{
Super::InitGame(MapName, Options, ErrorMessage);
auto spawnerIt = TActorIterator<AKOTHBossSpawner>(GetWorld(), AKOTHBossSpawner::StaticClass());
if(!spawnerIt)
{
GERROR("No instance of AKOTHBossSpawner found in the level, you need one when using the KOTH game mode!");
}
else
{
bossSpawner = *spawnerIt;
}
}
void AKingOfTheHillGameMode::HandleMatchHasStarted()
{
AKOTHGameState* gameState = GetGameState<AKOTHGameState>();
gameState->maxGameScore = maxGameScore;
TArray<int32> teamsize = gameState->GetTeamSizes();
for (int i = 0; i < teamsize.Num(); i++)
{
FKOTHTeamState state;
state.active = 0;
state.score = 0.0f;
state.maxScore = maxGameScore;
state.containsMembers = teamsize[i] > 0;
gameState->kothTeams.Add(state);
}
Super::HandleMatchHasStarted();
}
void AKingOfTheHillGameMode::Tick(float deltaTime)
{
Super::Tick(deltaTime);
AKOTHGameState* gameState = GetGameState<AKOTHGameState>();
for (int i = 0; i < gameState->kothTeams.Num(); i++)
{
FKOTHTeamState& state = gameState->kothTeams[i];
if(state.score >= maxGameScore)
{
// Check overtime condition
if(bossSpawner)
{
// Check overtime conditions / convert index to team index [0-4] -> [1-5]
if(!bossSpawner->IsContested(i + 1) && bossSpawner->IsBossAlive())
{
WinGame(i);
}
else
{
gameState->overtime = true;
}
}
}
if(state.active > 0)
{
state.active--;
}
}
}
void AKingOfTheHillGameMode::WinGame(int team)
{
TArray<class ANetworkCharacter*> players(m_players);
// Set winning team in gamestate (replicated)
GetGameState<ADefaultGameState>()->gameWinningTeam = team;
EndMatch();
// Destroy all player pawns so that they respawn as spectators
for (int32 i = 0; i < players.Num(); i++)
{
if(IsValid(players[i]))
{
players[i]->Destroy(true);
}
}
//TPRINT("Boss was killed. (ADefaultGameMode) the team = " + team);
}
void AKingOfTheHillGameMode::AddScore(int team, float duration)
{
// team to array index [1-5] -> [0-4]
team -= 1;
AKOTHGameState* gameState = GetGameState<AKOTHGameState>();
if(team < 0 || team >= gameState->kothTeams.Num())
return;
gameState->kothTeams[team].score += duration;
gameState->kothTeams[team].active = 2;
if(m_currentTeamWithHill != team)
{
gameState->BroadcastOnHillCaptured(team);
m_currentTeamWithHill = team;
}
}