// 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(TEXT("/Game/Assets/Blueprints/BP_DefaultPlayer")).Class; SpectatorClass = ConstructorHelpers::FClassFinder(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(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(); gameState->maxGameScore = maxGameScore; TArray 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(); 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 players(m_players); // Set winning team in gamestate (replicated) GetGameState()->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(); 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; } }