// Fill out your copyright notice in the Description page of Project Settings. #include "BlasterGameMode.h" #include "Blaster/Character/BlasterCharacter.h" #include "Blaster/GameState/BlasterGameState.h" #include "Blaster/PlayerController/BlasterPlayerController.h" #include "Blaster/PlayerState/BlasterPlayerState.h" #include "GameFramework/PlayerStart.h" #include "Kismet/GameplayStatics.h" namespace MatchState { const FName Cooldown = FName("Cooldown"); } ABlasterGameMode::ABlasterGameMode() { bDelayedStart = true; } void ABlasterGameMode::BeginPlay() { Super::BeginPlay(); LevelStartingTime = GetWorld()->GetTimeSeconds(); } void ABlasterGameMode::Tick(float DeltaTime) { Super::Tick(DeltaTime); if (MatchState == MatchState::WaitingToStart) { CountdownTime = WarmupTime - GetWorld()->GetTimeSeconds(); // + LevelStartingTime; if (CountdownTime <= 0.f) { StartMatch(); } } else if (MatchState == MatchState::InProgress) { CountdownTime = WarmupTime + MatchTime - GetWorld()->GetTimeSeconds(); // + LevelStartingTime; if (CountdownTime <= 0.f) { SetMatchState(MatchState::Cooldown); } } else if (MatchState == MatchState::Cooldown) { CountdownTime = WarmupTime + MatchTime + CooldownTime - GetWorld()->GetTimeSeconds(); // + LevelStartingTime; if (CountdownTime <= 0.f) { RestartGame(); } } } void ABlasterGameMode::OnMatchStateSet() { Super::OnMatchStateSet(); for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; ++It) { ABlasterPlayerController* BlasterPlayer = Cast(*It); if (BlasterPlayer) { BlasterPlayer->OnMatchStateSet(MatchState); } } } float ABlasterGameMode::CalculateDamage(AController* Attacker, AController* Victim, float BaseDamage) { return BaseDamage; } void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedCharacter, class ABlasterPlayerController* VictimController, ABlasterPlayerController* AttackerController) { if (AttackerController == nullptr || AttackerController->PlayerState == nullptr) return; if (VictimController == nullptr || VictimController->PlayerState == nullptr) return; ABlasterPlayerState* AttackerPlayerState = AttackerController ? Cast(AttackerController->PlayerState) : nullptr; ABlasterPlayerState* VictimPlayerState = VictimController ? Cast(VictimController->PlayerState) : nullptr; ABlasterGameState* BlasterGameState = GetGameState(); if (AttackerPlayerState && AttackerPlayerState != VictimPlayerState && BlasterGameState) { TArray PlayersCurrentlyInTheLead; for (auto LeadPlayer : BlasterGameState->TopScoringPlayers) { PlayersCurrentlyInTheLead.Add(LeadPlayer); } AttackerPlayerState->IncreaseScore(1.f); BlasterGameState->UpdateTopScore(AttackerPlayerState); if (BlasterGameState->TopScoringPlayers.Contains(AttackerPlayerState)) { ABlasterCharacter* Leader = Cast(AttackerPlayerState->GetPawn()); if (Leader) { Leader->MulticastGainedTheLead(); } } for (int32 i = 0; i < PlayersCurrentlyInTheLead.Num(); i++) { if (!BlasterGameState->TopScoringPlayers.Contains(PlayersCurrentlyInTheLead[i])) { ABlasterCharacter* Loser = Cast(PlayersCurrentlyInTheLead[i]->GetPawn()); if (Loser) { Loser->MulticastLostTheLead(); } } } } if (VictimPlayerState) { VictimPlayerState->IncreaseDefeats(1); } if (EliminatedCharacter) { EliminatedCharacter->Eliminated(false); } for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; ++It) { ABlasterPlayerController* BlasterPlayer = Cast(*It); if (BlasterPlayer && AttackerPlayerState && VictimPlayerState) { BlasterPlayer->BroadcastElim(AttackerPlayerState, VictimPlayerState); } } } void ABlasterGameMode::RequestRespawn(ACharacter* EliminatedCharacter, AController* EliminatedController) { if (EliminatedCharacter) { EliminatedCharacter->Reset(); EliminatedCharacter->Destroy(); } if (EliminatedController) { TArray PlayerStarts; UGameplayStatics::GetAllActorsOfClass(this, APlayerStart::StaticClass(), PlayerStarts); int32 Selection = FMath::RandRange(0, PlayerStarts.Num() - 1); RestartPlayerAtPlayerStart(EliminatedController, PlayerStarts[Selection]); } } void ABlasterGameMode::PlayerLeftGame(ABlasterPlayerState* PlayerLeaving) { if (PlayerLeaving == nullptr) return; ABlasterGameState* BlasterGameState = GetGameState(); if (BlasterGameState && BlasterGameState->TopScoringPlayers.Contains(PlayerLeaving)) { BlasterGameState->TopScoringPlayers.Remove(PlayerLeaving); } if (ABlasterCharacter* CharacterLeaving = Cast(PlayerLeaving->GetPawn())) { CharacterLeaving->Eliminated(true); } }