blaster/Source/Blaster/PlayerController/BlasterPlayerController.cpp

355 lines
10 KiB
C++
Raw Normal View History

2022-05-05 15:57:57 +00:00
// Fill out your copyright notice in the Description page of Project Settings.
#include "BlasterPlayerController.h"
2022-05-08 19:16:19 +00:00
#include "Blaster/Character/BlasterCharacter.h"
2022-05-10 14:03:35 +00:00
#include "Blaster/Components/CombatComponent.h"
2022-05-10 12:23:23 +00:00
#include "Blaster/GameMode/BlasterGameMode.h"
2022-05-10 11:31:39 +00:00
#include "Blaster/HUD/Announcement.h"
2022-05-07 10:03:33 +00:00
#include "Blaster/HUD/BlasterHUD.h"
#include "Blaster/HUD/CharacterOverlay.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
2022-05-10 10:42:09 +00:00
#include "GameFramework/GameMode.h"
2022-05-10 12:23:23 +00:00
#include "Kismet/GameplayStatics.h"
2022-05-10 10:42:09 +00:00
#include "Net/UnrealNetwork.h"
2022-05-07 10:03:33 +00:00
void ABlasterPlayerController::BeginPlay()
{
Super::BeginPlay();
2022-05-10 13:29:00 +00:00
2022-05-07 10:03:33 +00:00
BlasterHUD = Cast<ABlasterHUD>(GetHUD());
2022-05-10 12:23:23 +00:00
ServerCheckMatchState();
2022-05-07 10:03:33 +00:00
}
2022-05-10 10:42:09 +00:00
void ABlasterPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ABlasterPlayerController, MatchState);
}
2022-05-10 08:40:23 +00:00
void ABlasterPlayerController::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
2022-05-10 13:29:00 +00:00
2022-05-10 08:40:23 +00:00
SetHUDTime();
2022-05-10 09:14:54 +00:00
CheckTimeSync(DeltaSeconds);
2022-05-10 12:23:23 +00:00
PollInit();
2022-05-10 08:40:23 +00:00
}
2022-05-08 19:16:19 +00:00
void ABlasterPlayerController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
if (const ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(InPawn))
{
SetHUDHealth(BlasterCharacter->GetHealth(), BlasterCharacter->GetMaxHealth());
}
}
2022-05-10 09:14:54 +00:00
void ABlasterPlayerController::ReceivedPlayer()
{
Super::ReceivedPlayer();
if (IsLocalController())
{
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
}
}
void ABlasterPlayerController::CheckTimeSync(float DeltaSeconds)
{
TimeSyncRunningTime += DeltaSeconds;
if (IsLocalController() && TimeSyncRunningTime > TimeSyncFrequency)
{
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
TimeSyncRunningTime = 0.f;
}
}
float ABlasterPlayerController::GetServerTime()
{
if (HasAuthority()) return GetWorld()->GetTimeSeconds();
2022-05-10 10:42:09 +00:00
2022-05-10 09:14:54 +00:00
return GetWorld()->GetTimeSeconds() + ClientServerDelta;
}
2022-05-10 11:31:39 +00:00
void ABlasterPlayerController::HandleMatchHasStarted()
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
if (BlasterHUD)
{
BlasterHUD->AddCharacterOverlay();
if (BlasterHUD->Announcement)
{
BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Hidden);
}
}
}
2022-05-10 12:55:02 +00:00
void ABlasterPlayerController::HandleCooldown()
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
if (BlasterHUD)
{
BlasterHUD->CharacterOverlay->RemoveFromParent();
2022-05-10 13:29:00 +00:00
bool bHUDValid =
BlasterHUD->Announcement &&
BlasterHUD->Announcement->AnnouncementText &&
BlasterHUD->Announcement->AnnouncementMessage;
if (bHUDValid)
2022-05-10 12:55:02 +00:00
{
2022-05-10 13:29:00 +00:00
const FString AnnouncementText("New match starts in:");
BlasterHUD->Announcement->AnnouncementText->SetText(FText::FromString(AnnouncementText));
BlasterHUD->Announcement->AnnouncementMessage->SetText(FText());
2022-05-10 12:55:02 +00:00
BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Visible);
}
}
2022-05-10 14:03:35 +00:00
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(GetPawn());
if (BlasterCharacter && BlasterCharacter->GetCombat())
{
BlasterCharacter->bDisableGameplay = true;
BlasterCharacter->GetCombat()->FireButtonPressed(false);
}
2022-05-10 12:55:02 +00:00
}
2022-05-10 10:42:09 +00:00
void ABlasterPlayerController::OnMatchStateSet(FName State)
{
MatchState = State;
if (MatchState == MatchState::InProgress)
{
2022-05-10 11:31:39 +00:00
HandleMatchHasStarted();
2022-05-10 10:42:09 +00:00
}
2022-05-10 12:55:02 +00:00
else if (MatchState == MatchState::Cooldown)
{
HandleCooldown();
}
2022-05-10 10:42:09 +00:00
}
void ABlasterPlayerController::OnRep_MatchState()
{
if (MatchState == MatchState::InProgress)
{
2022-05-10 11:31:39 +00:00
HandleMatchHasStarted();
2022-05-10 10:42:09 +00:00
}
2022-05-10 12:55:02 +00:00
else if (MatchState == MatchState::Cooldown)
{
HandleCooldown();
}
2022-05-10 10:42:09 +00:00
}
2022-05-10 12:23:23 +00:00
void ABlasterPlayerController::ServerCheckMatchState_Implementation()
{
ABlasterGameMode* GameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
if (GameMode)
{
LevelStartingTime = GameMode->LevelStartingTime;
WarmupTime = GameMode->WarmupTime;
MatchTime = GameMode->MatchTime;
2022-05-10 13:29:00 +00:00
CooldownTime = GameMode->CooldownTime;
2022-05-10 12:23:23 +00:00
MatchState = GameMode->GetMatchState();
2022-05-10 13:29:00 +00:00
ClientJoinMidGame(MatchState, WarmupTime, MatchTime, CooldownTime, LevelStartingTime);
2022-05-10 12:23:23 +00:00
}
}
2022-05-10 13:29:00 +00:00
void ABlasterPlayerController::ClientJoinMidGame_Implementation(FName StateOfMatch, float Warmup, float Match, float Cooldown, float StartingTime)
2022-05-10 12:23:23 +00:00
{
LevelStartingTime = StartingTime;
WarmupTime = Warmup;
MatchTime = Match;
2022-05-10 13:29:00 +00:00
CooldownTime = Cooldown;
2022-05-10 12:23:23 +00:00
MatchState = StateOfMatch;
OnMatchStateSet(MatchState);
if (BlasterHUD && MatchState == MatchState::WaitingToStart)
{
BlasterHUD->AddAnnouncementOverlay();
}
}
2022-05-10 09:14:54 +00:00
void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest)
{
const float ServerTimeOfReceipt = GetWorld()->GetTimeSeconds();
ClientReportServerTime(TimeOfClientRequest, ServerTimeOfReceipt);
}
void ABlasterPlayerController::ClientReportServerTime_Implementation(float TimeOfClientRequest, float TimeServerReceivedClientRequest)
{
const float RoundTripTime = GetWorld()->GetTimeSeconds() - TimeOfClientRequest;
const float CurrentServerTime = TimeServerReceivedClientRequest + 0.5f * RoundTripTime;
ClientServerDelta = CurrentServerTime - GetWorld()->GetTimeSeconds();
}
2022-05-10 08:40:23 +00:00
void ABlasterPlayerController::SetHUDTime()
{
2022-05-10 12:23:23 +00:00
float TimeLeft = 0.f;
if (MatchState == MatchState::WaitingToStart) TimeLeft = WarmupTime - GetServerTime() + LevelStartingTime;
else if (MatchState == MatchState::InProgress) TimeLeft = WarmupTime + MatchTime - GetServerTime() + LevelStartingTime;
2022-05-10 13:29:00 +00:00
else if (MatchState == MatchState::Cooldown) TimeLeft = WarmupTime + MatchTime + CooldownTime - GetServerTime() + LevelStartingTime;
uint32 SecondsLeft = FMath::CeilToInt(TimeLeft);
if (HasAuthority())
{
BlasterGameMode = BlasterGameMode == nullptr ? Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this)) : BlasterGameMode;
if (BlasterGameMode)
{
SecondsLeft = FMath::CeilToInt(BlasterGameMode->GetCountdownTime() + LevelStartingTime);
}
}
2022-05-10 08:40:23 +00:00
if (CountdownInt != SecondsLeft)
{
2022-05-10 13:29:00 +00:00
if (MatchState == MatchState::WaitingToStart || MatchState == MatchState::Cooldown) SetHUDAnnouncementCountdown(TimeLeft);
if (MatchState == MatchState::InProgress) SetHUDMatchCountdown(TimeLeft);
2022-05-10 08:40:23 +00:00
}
2022-05-10 09:14:54 +00:00
2022-05-10 08:40:23 +00:00
CountdownInt = SecondsLeft;
}
2022-05-10 10:42:09 +00:00
void ABlasterPlayerController::PollInit()
{
if (CharacterOverlay == nullptr)
{
if (BlasterHUD && BlasterHUD->CharacterOverlay)
{
CharacterOverlay = BlasterHUD->CharacterOverlay;
if (CharacterOverlay)
{
SetHUDHealth(HUDHealth, HUDMaxHealth);
SetHUDScore(HUDScore);
SetHUDDefeats(HUDDefeats);
}
}
}
}
2022-05-07 10:03:33 +00:00
void ABlasterPlayerController::SetHUDHealth(float Health, float MaxHealth)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
2022-05-10 10:42:09 +00:00
bool bHUDValid = CharacterOverlay && CharacterOverlay->HealthBar && CharacterOverlay->HealthText;
2022-05-10 09:14:54 +00:00
2022-05-07 10:03:33 +00:00
if (bHUDValid)
{
const float HealthPercent = Health / MaxHealth;
BlasterHUD->CharacterOverlay->HealthBar->SetPercent(HealthPercent);
const FString HealthText = FString::Printf(TEXT("%d/%d"), FMath::CeilToInt(Health), FMath::CeilToInt(MaxHealth));
BlasterHUD->CharacterOverlay->HealthText->SetText(FText::FromString(HealthText));
}
2022-05-10 10:42:09 +00:00
else
{
bInitializeCharacterOverlay = true;
HUDHealth = Health;
HUDMaxHealth = MaxHealth;
}
2022-05-07 10:03:33 +00:00
}
2022-05-09 14:33:48 +00:00
void ABlasterPlayerController::SetHUDScore(float Score)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
2022-05-10 11:31:39 +00:00
bool bHUDValid = CharacterOverlay && CharacterOverlay->ScoreValue;
2022-05-09 14:33:48 +00:00
if (bHUDValid)
{
2022-05-09 15:16:41 +00:00
const FString ScoreAmount = FString::Printf(TEXT("%d"), FMath::FloorToInt(Score));
BlasterHUD->CharacterOverlay->ScoreValue->SetText(FText::FromString(ScoreAmount));
}
2022-05-10 10:42:09 +00:00
else
{
bInitializeCharacterOverlay = true;
HUDScore = Score;
}
2022-05-09 15:16:41 +00:00
}
void ABlasterPlayerController::SetHUDDefeats(int32 Defeats)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
2022-05-10 10:42:09 +00:00
bool bHUDValid = CharacterOverlay && CharacterOverlay->DefeatsValue;
2022-05-09 15:16:41 +00:00
if (bHUDValid)
{
const FString DefeatsAmount = FString::Printf(TEXT("%d"), Defeats);
BlasterHUD->CharacterOverlay->DefeatsValue->SetText(FText::FromString(DefeatsAmount));
2022-05-09 14:33:48 +00:00
}
2022-05-10 10:42:09 +00:00
else
{
bInitializeCharacterOverlay = true;
HUDDefeats = Defeats;
}
2022-05-09 14:33:48 +00:00
}
2022-05-09 16:39:41 +00:00
void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
2022-05-10 10:42:09 +00:00
bool bHUDValid = CharacterOverlay && CharacterOverlay->WeaponAmmoValue;
2022-05-09 16:39:41 +00:00
if (bHUDValid)
{
const FString WeaponAmmoAmount = FString::Printf(TEXT("%d"), Ammo);
BlasterHUD->CharacterOverlay->WeaponAmmoValue->SetText(FText::FromString(WeaponAmmoAmount));
}
}
2022-05-09 17:35:28 +00:00
void ABlasterPlayerController::SetHUDCarriedAmmo(int32 Ammo)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
2022-05-10 10:42:09 +00:00
bool bHUDValid = CharacterOverlay && CharacterOverlay->CarriedAmmoValue;
2022-05-09 17:35:28 +00:00
if (bHUDValid)
{
const FString CarriedAmmoAmount = FString::Printf(TEXT("%d"), Ammo);
BlasterHUD->CharacterOverlay->CarriedAmmoValue->SetText(FText::FromString(CarriedAmmoAmount));
}
}
2022-05-10 08:40:23 +00:00
void ABlasterPlayerController::SetHUDMatchCountdown(float CountdownTime)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
2022-05-10 10:42:09 +00:00
bool bHUDValid = CharacterOverlay && CharacterOverlay->MatchCountdownText;
2022-05-10 08:40:23 +00:00
if (bHUDValid)
{
2022-05-10 13:29:00 +00:00
if (CountdownTime < 0.f)
{
BlasterHUD->CharacterOverlay->MatchCountdownText->SetText(FText());
return;
}
2022-05-10 10:42:09 +00:00
const int32 Minutes = FMath::FloorToInt(CountdownTime / 60);
const int32 Seconds = CountdownTime - Minutes * 60;
2022-05-10 09:14:54 +00:00
2022-05-10 08:40:23 +00:00
const FString CountdownText = FString::Printf(TEXT("%02d:%02d"), Minutes, Seconds);
BlasterHUD->CharacterOverlay->MatchCountdownText->SetText(FText::FromString(CountdownText));
}
}
2022-05-10 12:23:23 +00:00
void ABlasterPlayerController::SetHUDAnnouncementCountdown(float CountdownTime)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
bool bHUDValid =
BlasterHUD &&
BlasterHUD->Announcement &&
BlasterHUD->Announcement->AnnouncementText &&
2022-05-10 13:29:00 +00:00
BlasterHUD->Announcement->CountdownText;
2022-05-10 12:23:23 +00:00
if (bHUDValid)
{
2022-05-10 13:29:00 +00:00
if (CountdownTime < 0.f)
{
BlasterHUD->Announcement->CountdownText->SetText(FText());
return;
}
2022-05-10 12:23:23 +00:00
const int32 Minutes = FMath::FloorToInt(CountdownTime / 60);
const int32 Seconds = CountdownTime - Minutes * 60;
const FString CountdownText = FString::Printf(TEXT("%02d:%02d"), Minutes, Seconds);
2022-05-10 13:29:00 +00:00
BlasterHUD->Announcement->CountdownText->SetText(FText::FromString(CountdownText));
2022-05-10 12:23:23 +00:00
}
}