reorg
This commit is contained in:
parent
68ef1dd118
commit
3e842336d0
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -27,7 +27,7 @@ ABlasterCharacter::ABlasterCharacter()
|
||||||
SpawnCollisionHandlingMethod = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
SpawnCollisionHandlingMethod = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
||||||
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
|
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
|
||||||
CameraBoom->SetupAttachment(GetMesh());
|
CameraBoom->SetupAttachment(GetMesh());
|
||||||
CameraBoom->TargetArmLength = 350.f;
|
CameraBoom->TargetArmLength = 600.f;
|
||||||
CameraBoom->bUsePawnControlRotation = true;
|
CameraBoom->bUsePawnControlRotation = true;
|
||||||
|
|
||||||
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
|
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
|
||||||
|
@ -44,11 +44,12 @@ ABlasterCharacter::ABlasterCharacter()
|
||||||
Combat->SetIsReplicated(true);
|
Combat->SetIsReplicated(true);
|
||||||
|
|
||||||
GetCharacterMovement()->NavAgentProps.bCanCrouch = true;
|
GetCharacterMovement()->NavAgentProps.bCanCrouch = true;
|
||||||
GetCapsuleComponent()->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore);
|
GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
|
||||||
GetMesh()->SetCollisionObjectType(ECC_SkeletalMesh);
|
GetMesh()->SetCollisionObjectType(ECC_SkeletalMesh);
|
||||||
GetMesh()->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore);
|
GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
|
||||||
GetMesh()->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
|
GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Block);
|
||||||
GetCharacterMovement()->RotationRate = FRotator(0.f, 850.f, 0.f);
|
GetCharacterMovement()->RotationRate = FRotator(0.f, 0.f, 850.f);
|
||||||
|
|
||||||
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
||||||
NetUpdateFrequency = 66.f;
|
NetUpdateFrequency = 66.f;
|
||||||
MinNetUpdateFrequency = 33.f;
|
MinNetUpdateFrequency = 33.f;
|
||||||
|
@ -56,17 +57,6 @@ ABlasterCharacter::ABlasterCharacter()
|
||||||
DissolveTimeline = CreateDefaultSubobject<UTimelineComponent>(TEXT("DissolveTimelineComponent"));
|
DissolveTimeline = CreateDefaultSubobject<UTimelineComponent>(TEXT("DissolveTimelineComponent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
UpdateHUDHealth();
|
|
||||||
if (HasAuthority())
|
|
||||||
{
|
|
||||||
OnTakeAnyDamage.AddDynamic(this, &ABlasterCharacter::ReceiveDamage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
void ABlasterCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||||
{
|
{
|
||||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||||
|
@ -79,76 +69,10 @@ void ABlasterCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Ou
|
||||||
void ABlasterCharacter::OnRep_ReplicatedMovement()
|
void ABlasterCharacter::OnRep_ReplicatedMovement()
|
||||||
{
|
{
|
||||||
Super::OnRep_ReplicatedMovement();
|
Super::OnRep_ReplicatedMovement();
|
||||||
|
|
||||||
SimProxiesTurn();
|
SimProxiesTurn();
|
||||||
TimeSinceLastMovementReplication = 0.f;
|
TimeSinceLastMovementReplication = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::Destroyed()
|
|
||||||
{
|
|
||||||
Super::Destroyed();
|
|
||||||
|
|
||||||
if (EliminationBotComponent)
|
|
||||||
{
|
|
||||||
EliminationBotComponent->DestroyComponent();
|
|
||||||
}
|
|
||||||
if (Combat && Combat->EquippedWeapon)
|
|
||||||
{
|
|
||||||
Combat->EquippedWeapon->Destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::PostInitializeComponents()
|
|
||||||
{
|
|
||||||
Super::PostInitializeComponents();
|
|
||||||
|
|
||||||
if (Combat)
|
|
||||||
{
|
|
||||||
Combat->Character = this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::PlayFireMontage(bool bAiming)
|
|
||||||
{
|
|
||||||
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
|
||||||
|
|
||||||
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
|
||||||
if (AnimInstance && FireWeaponMontage)
|
|
||||||
{
|
|
||||||
AnimInstance->Montage_Play(FireWeaponMontage);
|
|
||||||
const FName SectionName = bAiming ? FName("RifleADS") : FName("RifleHip");
|
|
||||||
AnimInstance->Montage_JumpToSection(SectionName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::PlayReloadMontage()
|
|
||||||
{
|
|
||||||
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
|
||||||
|
|
||||||
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
|
||||||
if (AnimInstance && ReloadMontage)
|
|
||||||
{
|
|
||||||
AnimInstance->Montage_Play(ReloadMontage);
|
|
||||||
FName SectionName;
|
|
||||||
switch (Combat->EquippedWeapon->GetWeaponType())
|
|
||||||
{
|
|
||||||
case EWeaponType::EWT_AssaultRifle:
|
|
||||||
SectionName = FName("Rifle");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
AnimInstance->Montage_JumpToSection(SectionName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::PlayEliminatedMontage()
|
|
||||||
{
|
|
||||||
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
|
||||||
if (AnimInstance && EliminatedMontage)
|
|
||||||
{
|
|
||||||
AnimInstance->Montage_Play(EliminatedMontage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::Eliminated()
|
void ABlasterCharacter::Eliminated()
|
||||||
{
|
{
|
||||||
if (Combat && Combat->EquippedWeapon)
|
if (Combat && Combat->EquippedWeapon)
|
||||||
|
@ -156,7 +80,12 @@ void ABlasterCharacter::Eliminated()
|
||||||
Combat->EquippedWeapon->Dropped();
|
Combat->EquippedWeapon->Dropped();
|
||||||
}
|
}
|
||||||
MulticastEliminated();
|
MulticastEliminated();
|
||||||
GetWorldTimerManager().SetTimer(EliminationTimer, this, &ABlasterCharacter::EliminationTimerFinished, EliminationDelay);
|
GetWorldTimerManager().SetTimer(
|
||||||
|
EliminationTimer,
|
||||||
|
this,
|
||||||
|
&ABlasterCharacter::EliminationTimerFinished,
|
||||||
|
EliminationDelay
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::MulticastEliminated_Implementation()
|
void ABlasterCharacter::MulticastEliminated_Implementation()
|
||||||
|
@ -182,7 +111,6 @@ void ABlasterCharacter::MulticastEliminated_Implementation()
|
||||||
GetCharacterMovement()->DisableMovement();
|
GetCharacterMovement()->DisableMovement();
|
||||||
GetCharacterMovement()->StopMovementImmediately();
|
GetCharacterMovement()->StopMovementImmediately();
|
||||||
bDisableGameplay = true;
|
bDisableGameplay = true;
|
||||||
|
|
||||||
// Disable collision
|
// Disable collision
|
||||||
GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
|
@ -190,13 +118,21 @@ void ABlasterCharacter::MulticastEliminated_Implementation()
|
||||||
// Elimination bot
|
// Elimination bot
|
||||||
if (EliminationBotEffect)
|
if (EliminationBotEffect)
|
||||||
{
|
{
|
||||||
const FVector EliminationBotSpawnPoint(GetActorLocation().X, GetActorLocation().Y, GetActorLocation().Z + 200.f);
|
FVector EliminationBotSpawnPoint(GetActorLocation().X, GetActorLocation().Y, GetActorLocation().Z + 200.f);
|
||||||
EliminationBotComponent = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), EliminationBotEffect, EliminationBotSpawnPoint, GetActorRotation());
|
EliminationBotComponent = UGameplayStatics::SpawnEmitterAtLocation(
|
||||||
|
GetWorld(),
|
||||||
|
EliminationBotEffect,
|
||||||
|
EliminationBotSpawnPoint,
|
||||||
|
GetActorRotation()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (EliminationBotSound)
|
if (EliminationBotSound)
|
||||||
{
|
{
|
||||||
UGameplayStatics::SpawnSoundAtLocation(this, EliminationBotSound, GetActorLocation());
|
UGameplayStatics::SpawnSoundAtLocation(
|
||||||
|
this,
|
||||||
|
EliminationBotSound,
|
||||||
|
GetActorLocation()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,40 +145,38 @@ void ABlasterCharacter::EliminationTimerFinished()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::PlayHitReactMontage()
|
void ABlasterCharacter::Destroyed()
|
||||||
{
|
{
|
||||||
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
Super::Destroyed();
|
||||||
|
|
||||||
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
if (EliminationBotComponent)
|
||||||
if (AnimInstance && HitReactMontage)
|
|
||||||
{
|
{
|
||||||
AnimInstance->Montage_Play(HitReactMontage);
|
EliminationBotComponent->DestroyComponent();
|
||||||
const FName SectionName = FName("FromFront");
|
}
|
||||||
AnimInstance->Montage_JumpToSection(SectionName);
|
if (Combat && Combat->EquippedWeapon)
|
||||||
|
{
|
||||||
|
Combat->EquippedWeapon->Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatorController,
|
void ABlasterCharacter::BeginPlay()
|
||||||
AActor* DamageCauser)
|
|
||||||
{
|
{
|
||||||
Health = FMath::Clamp(Health - Damage, 0.f, MaxHealth);
|
Super::BeginPlay();
|
||||||
|
|
||||||
UpdateHUDHealth();
|
UpdateHUDHealth();
|
||||||
if (Health > 0.f)
|
if (HasAuthority())
|
||||||
{
|
{
|
||||||
PlayHitReactMontage();
|
OnTakeAnyDamage.AddDynamic(this, &ABlasterCharacter::ReceiveDamage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Health == 0.f)
|
void ABlasterCharacter::Tick(float DeltaTime)
|
||||||
{
|
{
|
||||||
ABlasterGameMode* GameMode = GetWorld()->GetAuthGameMode<ABlasterGameMode>();
|
Super::Tick(DeltaTime);
|
||||||
if (GameMode)
|
|
||||||
{
|
RotateInPlace(DeltaTime);
|
||||||
BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;
|
HideCameraIfCharacterClose();
|
||||||
ABlasterPlayerController* AttackerController = Cast<ABlasterPlayerController>(InstigatorController);
|
PollInit();
|
||||||
GameMode->PlayerEliminated(this, BlasterPlayerController, AttackerController);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::RotateInPlace(float DeltaTime)
|
void ABlasterCharacter::RotateInPlace(float DeltaTime)
|
||||||
|
@ -253,7 +187,7 @@ void ABlasterCharacter::RotateInPlace(float DeltaTime)
|
||||||
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GetLocalRole() > ROLE_SimulatedProxy && IsLocallyControlled())
|
if (GetLocalRole() > ENetRole::ROLE_SimulatedProxy && IsLocallyControlled())
|
||||||
{
|
{
|
||||||
AimOffset(DeltaTime);
|
AimOffset(DeltaTime);
|
||||||
}
|
}
|
||||||
|
@ -268,46 +202,108 @@ void ABlasterCharacter::RotateInPlace(float DeltaTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::Tick(float DeltaTime)
|
|
||||||
{
|
|
||||||
Super::Tick(DeltaTime);
|
|
||||||
|
|
||||||
RotateInPlace(DeltaTime);
|
|
||||||
HideCameraIfCharacterClose();
|
|
||||||
PollInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::PollInit()
|
|
||||||
{
|
|
||||||
if (BlasterPlayerState == nullptr)
|
|
||||||
{
|
|
||||||
BlasterPlayerState = GetPlayerState<ABlasterPlayerState>();
|
|
||||||
if (BlasterPlayerState)
|
|
||||||
{
|
|
||||||
// Initialize Score now we have the PlayerState
|
|
||||||
BlasterPlayerState->IncreaseScore(0.f);
|
|
||||||
BlasterPlayerState->IncreaseDefeats(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
void ABlasterCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
||||||
{
|
{
|
||||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||||
|
|
||||||
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ABlasterCharacter::Jump);
|
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ABlasterCharacter::Jump);
|
||||||
PlayerInputComponent->BindAction("Equip", IE_Pressed, this, &ABlasterCharacter::EquipButtonPressed);
|
|
||||||
PlayerInputComponent->BindAction("Reload", IE_Pressed, this, &ABlasterCharacter::ReloadButtonPressed);
|
|
||||||
PlayerInputComponent->BindAction("Crouch", IE_Pressed, this, &ABlasterCharacter::CrouchButtonPressed);
|
|
||||||
PlayerInputComponent->BindAction("Aim", IE_Pressed, this, &ABlasterCharacter::AimButtonPressed);
|
|
||||||
PlayerInputComponent->BindAction("Aim", IE_Released, this, &ABlasterCharacter::AimButtonReleased);
|
|
||||||
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &ABlasterCharacter::FireButtonPressed);
|
|
||||||
PlayerInputComponent->BindAction("Fire", IE_Released, this, &ABlasterCharacter::FireButtonReleased);
|
|
||||||
|
|
||||||
PlayerInputComponent->BindAxis("MoveForward", this, &ABlasterCharacter::MoveForward);
|
PlayerInputComponent->BindAxis("MoveForward", this, &ABlasterCharacter::MoveForward);
|
||||||
PlayerInputComponent->BindAxis("MoveRight", this, &ABlasterCharacter::MoveRight);
|
PlayerInputComponent->BindAxis("MoveRight", this, &ABlasterCharacter::MoveRight);
|
||||||
PlayerInputComponent->BindAxis("Turn", this, &ABlasterCharacter::Turn);
|
PlayerInputComponent->BindAxis("Turn", this, &ABlasterCharacter::Turn);
|
||||||
PlayerInputComponent->BindAxis("LookUp", this, &ABlasterCharacter::LookUp);
|
PlayerInputComponent->BindAxis("LookUp", this, &ABlasterCharacter::LookUp);
|
||||||
|
|
||||||
|
PlayerInputComponent->BindAction("Equip", IE_Pressed, this, &ABlasterCharacter::EquipButtonPressed);
|
||||||
|
PlayerInputComponent->BindAction("Crouch", IE_Pressed, this, &ABlasterCharacter::CrouchButtonPressed);
|
||||||
|
PlayerInputComponent->BindAction("Aim", IE_Pressed, this, &ABlasterCharacter::AimButtonPressed);
|
||||||
|
PlayerInputComponent->BindAction("Aim", IE_Released, this, &ABlasterCharacter::AimButtonReleased);
|
||||||
|
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &ABlasterCharacter::FireButtonPressed);
|
||||||
|
PlayerInputComponent->BindAction("Fire", IE_Released, this, &ABlasterCharacter::FireButtonReleased);
|
||||||
|
PlayerInputComponent->BindAction("Reload", IE_Pressed, this, &ABlasterCharacter::ReloadButtonPressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::PostInitializeComponents()
|
||||||
|
{
|
||||||
|
Super::PostInitializeComponents();
|
||||||
|
if (Combat)
|
||||||
|
{
|
||||||
|
Combat->Character = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::PlayFireMontage(bool bAiming)
|
||||||
|
{
|
||||||
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
|
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
||||||
|
if (AnimInstance && FireWeaponMontage)
|
||||||
|
{
|
||||||
|
AnimInstance->Montage_Play(FireWeaponMontage);
|
||||||
|
FName SectionName;
|
||||||
|
SectionName = bAiming ? FName("RifleAim") : FName("RifleHip");
|
||||||
|
AnimInstance->Montage_JumpToSection(SectionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::PlayReloadMontage()
|
||||||
|
{
|
||||||
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
|
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
||||||
|
if (AnimInstance && ReloadMontage)
|
||||||
|
{
|
||||||
|
AnimInstance->Montage_Play(ReloadMontage);
|
||||||
|
FName SectionName;
|
||||||
|
|
||||||
|
switch (Combat->EquippedWeapon->GetWeaponType())
|
||||||
|
{
|
||||||
|
case EWeaponType::EWT_AssaultRifle:
|
||||||
|
SectionName = FName("Rifle");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimInstance->Montage_JumpToSection(SectionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::PlayEliminatedMontage()
|
||||||
|
{
|
||||||
|
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
||||||
|
if (AnimInstance && EliminatedMontage)
|
||||||
|
{
|
||||||
|
AnimInstance->Montage_Play(EliminatedMontage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::PlayHitReactMontage()
|
||||||
|
{
|
||||||
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
|
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
||||||
|
if (AnimInstance && HitReactMontage)
|
||||||
|
{
|
||||||
|
AnimInstance->Montage_Play(HitReactMontage);
|
||||||
|
FName SectionName("FromFront");
|
||||||
|
AnimInstance->Montage_JumpToSection(SectionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatorController, AActor* DamageCauser)
|
||||||
|
{
|
||||||
|
Health = FMath::Clamp(Health - Damage, 0.f, MaxHealth);
|
||||||
|
UpdateHUDHealth();
|
||||||
|
if (Health > 0.f) PlayHitReactMontage();
|
||||||
|
|
||||||
|
if (Health == 0.f)
|
||||||
|
{
|
||||||
|
ABlasterGameMode* BlasterGameMode = GetWorld()->GetAuthGameMode<ABlasterGameMode>();
|
||||||
|
if (BlasterGameMode)
|
||||||
|
{
|
||||||
|
BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;
|
||||||
|
ABlasterPlayerController* AttackerController = Cast<ABlasterPlayerController>(InstigatorController);
|
||||||
|
BlasterGameMode->PlayerEliminated(this, BlasterPlayerController, AttackerController);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::MoveForward(float Value)
|
void ABlasterCharacter::MoveForward(float Value)
|
||||||
|
@ -317,7 +313,6 @@ void ABlasterCharacter::MoveForward(float Value)
|
||||||
{
|
{
|
||||||
const FRotator YawRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
|
const FRotator YawRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
|
||||||
const FVector Direction(FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X));
|
const FVector Direction(FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X));
|
||||||
|
|
||||||
AddMovementInput(Direction, Value);
|
AddMovementInput(Direction, Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,7 +324,6 @@ void ABlasterCharacter::MoveRight(float Value)
|
||||||
{
|
{
|
||||||
const FRotator YawRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
|
const FRotator YawRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
|
||||||
const FVector Direction(FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y));
|
const FVector Direction(FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y));
|
||||||
|
|
||||||
AddMovementInput(Direction, Value);
|
AddMovementInput(Direction, Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,12 +354,11 @@ void ABlasterCharacter::EquipButtonPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::ReloadButtonPressed()
|
void ABlasterCharacter::ServerEquipButtonPressed_Implementation()
|
||||||
{
|
{
|
||||||
if (bDisableGameplay) return;
|
|
||||||
if (Combat)
|
if (Combat)
|
||||||
{
|
{
|
||||||
Combat->Reload();
|
Combat->EquipWeapon(OverlappingWeapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,6 +375,15 @@ void ABlasterCharacter::CrouchButtonPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::ReloadButtonPressed()
|
||||||
|
{
|
||||||
|
if (bDisableGameplay) return;
|
||||||
|
if (Combat)
|
||||||
|
{
|
||||||
|
Combat->Reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::AimButtonPressed()
|
void ABlasterCharacter::AimButtonPressed()
|
||||||
{
|
{
|
||||||
if (bDisableGameplay) return;
|
if (bDisableGameplay) return;
|
||||||
|
@ -400,47 +402,24 @@ void ABlasterCharacter::AimButtonReleased()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::Jump()
|
float ABlasterCharacter::CalculateSpeed()
|
||||||
{
|
{
|
||||||
if (bDisableGameplay) return;
|
FVector Velocity = GetVelocity();
|
||||||
if (bIsCrouched)
|
Velocity.Z = 0.f;
|
||||||
{
|
return Velocity.Size();
|
||||||
UnCrouch();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Super::Jump();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::FireButtonPressed()
|
|
||||||
{
|
|
||||||
if (Combat)
|
|
||||||
{
|
|
||||||
Combat->FireButtonPressed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::FireButtonReleased()
|
|
||||||
{
|
|
||||||
if (Combat)
|
|
||||||
{
|
|
||||||
Combat->FireButtonPressed(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::AimOffset(float DeltaTime)
|
void ABlasterCharacter::AimOffset(float DeltaTime)
|
||||||
{
|
{
|
||||||
if (Combat && Combat->EquippedWeapon == nullptr) return;
|
if (Combat && Combat->EquippedWeapon == nullptr) return;
|
||||||
|
float Speed = CalculateSpeed();
|
||||||
|
bool bIsInAir = GetCharacterMovement()->IsFalling();
|
||||||
|
|
||||||
const float Speed = CalculateSpeed();
|
if (Speed == 0.f && !bIsInAir) // standing still, not jumping
|
||||||
const bool bIsInAir = GetCharacterMovement()->IsFalling();
|
|
||||||
|
|
||||||
if (Speed == 0.f && !bIsInAir) // Standing still, not jumping
|
|
||||||
{
|
{
|
||||||
bRotateRootBone = true;
|
bRotateRootBone = true;
|
||||||
const FRotator CurrentAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
|
FRotator CurrentAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
|
||||||
const FRotator DeltaAimRotation = UKismetMathLibrary::NormalizedDeltaRotator(CurrentAimRotation, StartingAimRotation);
|
FRotator DeltaAimRotation = UKismetMathLibrary::NormalizedDeltaRotator(CurrentAimRotation, StartingAimRotation);
|
||||||
AO_Yaw = DeltaAimRotation.Yaw;
|
AO_Yaw = DeltaAimRotation.Yaw;
|
||||||
if (TurningInPlace == ETurningInPlace::ETIP_NotTurning)
|
if (TurningInPlace == ETurningInPlace::ETIP_NotTurning)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +428,7 @@ void ABlasterCharacter::AimOffset(float DeltaTime)
|
||||||
bUseControllerRotationYaw = true;
|
bUseControllerRotationYaw = true;
|
||||||
TurnInPlace(DeltaTime);
|
TurnInPlace(DeltaTime);
|
||||||
}
|
}
|
||||||
if (Speed > 0.f || bIsInAir) // Running or jumping
|
if (Speed > 0.f || bIsInAir) // running, or jumping
|
||||||
{
|
{
|
||||||
bRotateRootBone = false;
|
bRotateRootBone = false;
|
||||||
StartingAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
|
StartingAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
|
||||||
|
@ -464,13 +443,11 @@ void ABlasterCharacter::AimOffset(float DeltaTime)
|
||||||
void ABlasterCharacter::CalculateAO_Pitch()
|
void ABlasterCharacter::CalculateAO_Pitch()
|
||||||
{
|
{
|
||||||
AO_Pitch = GetBaseAimRotation().Pitch;
|
AO_Pitch = GetBaseAimRotation().Pitch;
|
||||||
|
|
||||||
// Fix pitch/yaw compression
|
|
||||||
if (AO_Pitch > 90.f && !IsLocallyControlled())
|
if (AO_Pitch > 90.f && !IsLocallyControlled())
|
||||||
{
|
{
|
||||||
// map pitch from [270, 360) to [-90, 0)
|
// map pitch from [270, 360) to [-90, 0)
|
||||||
const FVector2d InRange(270.f, 360.f);
|
FVector2D InRange(270.f, 360.f);
|
||||||
const FVector2d OutRange(-90.f, 0.f);
|
FVector2D OutRange(-90.f, 0.f);
|
||||||
AO_Pitch = FMath::GetMappedRangeValueClamped(InRange, OutRange, AO_Pitch);
|
AO_Pitch = FMath::GetMappedRangeValueClamped(InRange, OutRange, AO_Pitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,10 +455,8 @@ void ABlasterCharacter::CalculateAO_Pitch()
|
||||||
void ABlasterCharacter::SimProxiesTurn()
|
void ABlasterCharacter::SimProxiesTurn()
|
||||||
{
|
{
|
||||||
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
bRotateRootBone = false;
|
bRotateRootBone = false;
|
||||||
|
float Speed = CalculateSpeed();
|
||||||
const float Speed = CalculateSpeed();
|
|
||||||
if (Speed > 0.f)
|
if (Speed > 0.f)
|
||||||
{
|
{
|
||||||
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
||||||
|
@ -508,13 +483,38 @@ void ABlasterCharacter::SimProxiesTurn()
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
TurningInPlace = ETurningInPlace::ETIP_NotTurning;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::ServerEquipButtonPressed_Implementation()
|
void ABlasterCharacter::Jump()
|
||||||
{
|
{
|
||||||
EquipButtonPressed();
|
if (bDisableGameplay) return;
|
||||||
|
if (bIsCrouched)
|
||||||
|
{
|
||||||
|
UnCrouch();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Super::Jump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::FireButtonPressed()
|
||||||
|
{
|
||||||
|
if (bDisableGameplay) return;
|
||||||
|
if (Combat)
|
||||||
|
{
|
||||||
|
Combat->FireButtonPressed(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::FireButtonReleased()
|
||||||
|
{
|
||||||
|
if (bDisableGameplay) return;
|
||||||
|
if (Combat)
|
||||||
|
{
|
||||||
|
Combat->FireButtonPressed(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::TurnInPlace(float DeltaTime)
|
void ABlasterCharacter::TurnInPlace(float DeltaTime)
|
||||||
|
@ -537,18 +537,6 @@ void ABlasterCharacter::TurnInPlace(float DeltaTime)
|
||||||
StartingAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
|
StartingAimRotation = FRotator(0.f, GetBaseAimRotation().Yaw, 0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// switch (TurningInPlace)
|
|
||||||
// {
|
|
||||||
// case ETurningInPlace::ETIP_Left:
|
|
||||||
// UE_LOG(LogTemp, Warning, TEXT("TurningInPlace: Left"));
|
|
||||||
// break;
|
|
||||||
// case ETurningInPlace::ETIP_Right:
|
|
||||||
// UE_LOG(LogTemp, Warning, TEXT("TurningInPlace: Right"));
|
|
||||||
// break;
|
|
||||||
// case ETurningInPlace::ETIP_NotTurning:
|
|
||||||
// UE_LOG(LogTemp, Warning, TEXT("TurningInPlace: NotTurning"));
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::HideCameraIfCharacterClose()
|
void ABlasterCharacter::HideCameraIfCharacterClose()
|
||||||
|
@ -572,20 +560,10 @@ void ABlasterCharacter::HideCameraIfCharacterClose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float ABlasterCharacter::CalculateSpeed()
|
|
||||||
{
|
|
||||||
FVector Velocity = GetVelocity();
|
|
||||||
Velocity.Z = 0.f;
|
|
||||||
return Velocity.Size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterCharacter::OnRep_Health()
|
void ABlasterCharacter::OnRep_Health()
|
||||||
{
|
{
|
||||||
UpdateHUDHealth();
|
UpdateHUDHealth();
|
||||||
if (Health > 0.f)
|
if (Health > 0.f) PlayHitReactMontage();
|
||||||
{
|
|
||||||
PlayHitReactMontage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::UpdateHUDHealth()
|
void ABlasterCharacter::UpdateHUDHealth()
|
||||||
|
@ -597,6 +575,19 @@ void ABlasterCharacter::UpdateHUDHealth()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::PollInit()
|
||||||
|
{
|
||||||
|
if (BlasterPlayerState == nullptr)
|
||||||
|
{
|
||||||
|
BlasterPlayerState = GetPlayerState<ABlasterPlayerState>();
|
||||||
|
if (BlasterPlayerState)
|
||||||
|
{
|
||||||
|
BlasterPlayerState->AddToScore(0.f);
|
||||||
|
BlasterPlayerState->AddToDefeats(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::UpdateDissolveMaterial(float DissolveValue)
|
void ABlasterCharacter::UpdateDissolveMaterial(float DissolveValue)
|
||||||
{
|
{
|
||||||
if (DynamicDissolveMaterialInstance)
|
if (DynamicDissolveMaterialInstance)
|
||||||
|
@ -621,7 +612,6 @@ void ABlasterCharacter::SetOverlappingWeapon(AWeapon* Weapon)
|
||||||
{
|
{
|
||||||
OverlappingWeapon->ShowPickupWidget(false);
|
OverlappingWeapon->ShowPickupWidget(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlappingWeapon = Weapon;
|
OverlappingWeapon = Weapon;
|
||||||
if (IsLocallyControlled())
|
if (IsLocallyControlled())
|
||||||
{
|
{
|
||||||
|
@ -632,6 +622,18 @@ void ABlasterCharacter::SetOverlappingWeapon(AWeapon* Weapon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::OnRep_OverlappingWeapon(AWeapon* LastWeapon)
|
||||||
|
{
|
||||||
|
if (OverlappingWeapon)
|
||||||
|
{
|
||||||
|
OverlappingWeapon->ShowPickupWidget(true);
|
||||||
|
}
|
||||||
|
if (LastWeapon)
|
||||||
|
{
|
||||||
|
LastWeapon->ShowPickupWidget(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ABlasterCharacter::IsWeaponEquipped()
|
bool ABlasterCharacter::IsWeaponEquipped()
|
||||||
{
|
{
|
||||||
return Combat && Combat->EquippedWeapon;
|
return Combat && Combat->EquippedWeapon;
|
||||||
|
@ -645,14 +647,12 @@ bool ABlasterCharacter::IsAiming()
|
||||||
AWeapon* ABlasterCharacter::GetEquippedWeapon()
|
AWeapon* ABlasterCharacter::GetEquippedWeapon()
|
||||||
{
|
{
|
||||||
if (Combat == nullptr) return nullptr;
|
if (Combat == nullptr) return nullptr;
|
||||||
|
|
||||||
return Combat->EquippedWeapon;
|
return Combat->EquippedWeapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector ABlasterCharacter::GetHitTarget() const
|
FVector ABlasterCharacter::GetHitTarget() const
|
||||||
{
|
{
|
||||||
if (Combat == nullptr) return FVector();
|
if (Combat == nullptr) return FVector();
|
||||||
|
|
||||||
return Combat->HitTarget;
|
return Combat->HitTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,15 +661,3 @@ ECombatState ABlasterCharacter::GetCombatState() const
|
||||||
if (Combat == nullptr) return ECombatState::ECS_MAX;
|
if (Combat == nullptr) return ECombatState::ECS_MAX;
|
||||||
return Combat->CombatState;
|
return Combat->CombatState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::OnRep_OverlappingWeapon(AWeapon* LastWeapon)
|
|
||||||
{
|
|
||||||
if (OverlappingWeapon)
|
|
||||||
{
|
|
||||||
OverlappingWeapon->ShowPickupWidget(true);
|
|
||||||
}
|
|
||||||
if (LastWeapon)
|
|
||||||
{
|
|
||||||
LastWeapon->ShowPickupWidget(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Blaster/Interfaces/InteractWithCrosshairInterface.h"
|
#include "Blaster/Interfaces/InteractWithCrosshairsInterface.h"
|
||||||
#include "Blaster/Types/CombatState.h"
|
#include "Blaster/Types/CombatState.h"
|
||||||
#include "Blaster/Types/TurningInPlace.h"
|
#include "Blaster/Types/TurningInPlace.h"
|
||||||
#include "Components/TimelineComponent.h"
|
#include "Components/TimelineComponent.h"
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
#include "BlasterCharacter.generated.h"
|
#include "BlasterCharacter.generated.h"
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class BLASTER_API ABlasterCharacter : public ACharacter, public IInteractWithCrosshairInterface
|
class BLASTER_API ABlasterCharacter : public ACharacter, public IInteractWithCrosshairsInterface
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "CombatComponent.h"
|
#include "CombatComponent.h"
|
||||||
|
|
||||||
#include "Blaster/Character/BlasterCharacter.h"
|
#include "Blaster/Character/BlasterCharacter.h"
|
||||||
|
#include "Blaster/Interfaces/InteractWithCrosshairsInterface.h"
|
||||||
#include "Blaster/PlayerController/BlasterPlayerController.h"
|
#include "Blaster/PlayerController/BlasterPlayerController.h"
|
||||||
#include "Blaster/Weapon/Weapon.h"
|
#include "Blaster/Weapon/Weapon.h"
|
||||||
#include "Camera/CameraComponent.h"
|
#include "Camera/CameraComponent.h"
|
||||||
|
@ -17,7 +18,7 @@ UCombatComponent::UCombatComponent()
|
||||||
PrimaryComponentTick.bCanEverTick = true;
|
PrimaryComponentTick.bCanEverTick = true;
|
||||||
|
|
||||||
BaseWalkSpeed = 600.f;
|
BaseWalkSpeed = 600.f;
|
||||||
AimWalkSpeed = 350.f;
|
AimWalkSpeed = 450.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||||
|
@ -25,8 +26,8 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out
|
||||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||||
|
|
||||||
DOREPLIFETIME(UCombatComponent, EquippedWeapon);
|
DOREPLIFETIME(UCombatComponent, EquippedWeapon);
|
||||||
DOREPLIFETIME_CONDITION(UCombatComponent, CarriedAmmo, COND_OwnerOnly);
|
|
||||||
DOREPLIFETIME(UCombatComponent, bAiming);
|
DOREPLIFETIME(UCombatComponent, bAiming);
|
||||||
|
DOREPLIFETIME_CONDITION(UCombatComponent, CarriedAmmo, COND_OwnerOnly);
|
||||||
DOREPLIFETIME(UCombatComponent, CombatState);
|
DOREPLIFETIME(UCombatComponent, CombatState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +66,273 @@ void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::FireButtonPressed(bool bPressed)
|
||||||
|
{
|
||||||
|
bFireButtonPressed = bPressed;
|
||||||
|
if (bFireButtonPressed && EquippedWeapon)
|
||||||
|
{
|
||||||
|
Fire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::Fire()
|
||||||
|
{
|
||||||
|
if (CanFire())
|
||||||
|
{
|
||||||
|
bCanFire = false;
|
||||||
|
ServerFire(HitTarget);
|
||||||
|
if (EquippedWeapon)
|
||||||
|
{
|
||||||
|
CrosshairShootingFactor = .75f;
|
||||||
|
}
|
||||||
|
StartFireTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::StartFireTimer()
|
||||||
|
{
|
||||||
|
if (EquippedWeapon == nullptr || Character == nullptr) return;
|
||||||
|
Character->GetWorldTimerManager().SetTimer(
|
||||||
|
FireTimer,
|
||||||
|
this,
|
||||||
|
&UCombatComponent::FireTimerFinished,
|
||||||
|
EquippedWeapon->FireDelay
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::FireTimerFinished()
|
||||||
|
{
|
||||||
|
if (EquippedWeapon == nullptr) return;
|
||||||
|
bCanFire = true;
|
||||||
|
if (bFireButtonPressed && EquippedWeapon->bAutomatic)
|
||||||
|
{
|
||||||
|
Fire();
|
||||||
|
}
|
||||||
|
if (EquippedWeapon->IsEmpty())
|
||||||
|
{
|
||||||
|
Reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
|
||||||
|
{
|
||||||
|
MulticastFire(TraceHitTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
|
||||||
|
{
|
||||||
|
if (EquippedWeapon == nullptr) return;
|
||||||
|
if (Character && CombatState == ECombatState::ECS_Unoccupied)
|
||||||
|
{
|
||||||
|
Character->PlayFireMontage(bAiming);
|
||||||
|
EquippedWeapon->Fire(TraceHitTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip)
|
||||||
|
{
|
||||||
|
if (Character == nullptr || WeaponToEquip == nullptr) return;
|
||||||
|
if (EquippedWeapon)
|
||||||
|
{
|
||||||
|
EquippedWeapon->Dropped();
|
||||||
|
}
|
||||||
|
EquippedWeapon = WeaponToEquip;
|
||||||
|
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
||||||
|
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));
|
||||||
|
if (HandSocket)
|
||||||
|
{
|
||||||
|
HandSocket->AttachActor(EquippedWeapon, Character->GetMesh());
|
||||||
|
}
|
||||||
|
EquippedWeapon->SetOwner(Character);
|
||||||
|
EquippedWeapon->SetHUDAmmo();
|
||||||
|
|
||||||
|
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
||||||
|
{
|
||||||
|
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
|
if (Controller)
|
||||||
|
{
|
||||||
|
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EquippedWeapon->EquipSound)
|
||||||
|
{
|
||||||
|
UGameplayStatics::PlaySoundAtLocation(
|
||||||
|
this,
|
||||||
|
EquippedWeapon->EquipSound,
|
||||||
|
Character->GetActorLocation()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EquippedWeapon->IsEmpty())
|
||||||
|
{
|
||||||
|
Reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
|
||||||
|
Character->bUseControllerRotationYaw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::Reload()
|
||||||
|
{
|
||||||
|
if (CarriedAmmo > 0 && CombatState != ECombatState::ECS_Reloading)
|
||||||
|
{
|
||||||
|
ServerReload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::ServerReload_Implementation()
|
||||||
|
{
|
||||||
|
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
|
// return if weapon mag is at max capacity
|
||||||
|
if (EquippedWeapon->GetAmmo() == EquippedWeapon->GetMagCapacity()) return;
|
||||||
|
|
||||||
|
CombatState = ECombatState::ECS_Reloading;
|
||||||
|
HandleReload();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::FinishedReloading()
|
||||||
|
{
|
||||||
|
if (Character == nullptr) return;
|
||||||
|
if (Character->HasAuthority())
|
||||||
|
{
|
||||||
|
CombatState = ECombatState::ECS_Unoccupied;
|
||||||
|
UpdateAmmoValues();
|
||||||
|
}
|
||||||
|
if (bFireButtonPressed)
|
||||||
|
{
|
||||||
|
Fire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::UpdateAmmoValues()
|
||||||
|
{
|
||||||
|
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
||||||
|
int32 ReloadAmount = AmountToReload();
|
||||||
|
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
||||||
|
{
|
||||||
|
CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= ReloadAmount;
|
||||||
|
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
||||||
|
}
|
||||||
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
|
if (Controller)
|
||||||
|
{
|
||||||
|
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
||||||
|
}
|
||||||
|
EquippedWeapon->AddAmmo(-ReloadAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::OnRep_CombatState()
|
||||||
|
{
|
||||||
|
switch (CombatState)
|
||||||
|
{
|
||||||
|
case ECombatState::ECS_Reloading:
|
||||||
|
HandleReload();
|
||||||
|
break;
|
||||||
|
case ECombatState::ECS_Unoccupied:
|
||||||
|
if (bFireButtonPressed)
|
||||||
|
{
|
||||||
|
Fire();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::HandleReload()
|
||||||
|
{
|
||||||
|
Character->PlayReloadMontage();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 UCombatComponent::AmountToReload()
|
||||||
|
{
|
||||||
|
if (EquippedWeapon == nullptr) return 0;
|
||||||
|
int32 RoomInMag = EquippedWeapon->GetMagCapacity() - EquippedWeapon->GetAmmo();
|
||||||
|
|
||||||
|
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
||||||
|
{
|
||||||
|
int32 AmountCarried = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
||||||
|
int32 Least = FMath::Min(RoomInMag, AmountCarried);
|
||||||
|
return FMath::Clamp(RoomInMag, 0, Least);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::OnRep_EquippedWeapon()
|
||||||
|
{
|
||||||
|
if (EquippedWeapon && Character)
|
||||||
|
{
|
||||||
|
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
||||||
|
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));
|
||||||
|
if (HandSocket)
|
||||||
|
{
|
||||||
|
HandSocket->AttachActor(EquippedWeapon, Character->GetMesh());
|
||||||
|
}
|
||||||
|
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
|
||||||
|
Character->bUseControllerRotationYaw = true;
|
||||||
|
|
||||||
|
if (EquippedWeapon->EquipSound)
|
||||||
|
{
|
||||||
|
UGameplayStatics::PlaySoundAtLocation(
|
||||||
|
this,
|
||||||
|
EquippedWeapon->EquipSound,
|
||||||
|
Character->GetActorLocation()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
|
||||||
|
{
|
||||||
|
FVector2D ViewportSize;
|
||||||
|
if (GEngine && GEngine->GameViewport)
|
||||||
|
{
|
||||||
|
GEngine->GameViewport->GetViewportSize(ViewportSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector2D CrosshairLocation(ViewportSize.X / 2.f, ViewportSize.Y / 2.f);
|
||||||
|
FVector CrosshairWorldPosition;
|
||||||
|
FVector CrosshairWorldDirection;
|
||||||
|
bool bScreenToWorld = UGameplayStatics::DeprojectScreenToWorld(
|
||||||
|
UGameplayStatics::GetPlayerController(this, 0),
|
||||||
|
CrosshairLocation,
|
||||||
|
CrosshairWorldPosition,
|
||||||
|
CrosshairWorldDirection
|
||||||
|
);
|
||||||
|
|
||||||
|
if (bScreenToWorld)
|
||||||
|
{
|
||||||
|
FVector Start = CrosshairWorldPosition;
|
||||||
|
|
||||||
|
if (Character)
|
||||||
|
{
|
||||||
|
float DistanceToCharacter = (Character->GetActorLocation() - Start).Size();
|
||||||
|
Start += CrosshairWorldDirection * (DistanceToCharacter + 100.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector End = Start + CrosshairWorldDirection * TRACE_LENGTH;
|
||||||
|
|
||||||
|
GetWorld()->LineTraceSingleByChannel(
|
||||||
|
TraceHitResult,
|
||||||
|
Start,
|
||||||
|
End,
|
||||||
|
ECollisionChannel::ECC_Visibility
|
||||||
|
);
|
||||||
|
if (TraceHitResult.GetActor() && TraceHitResult.GetActor()->Implements<UInteractWithCrosshairsInterface>())
|
||||||
|
{
|
||||||
|
HUDPackage.CrosshairsColor = FLinearColor::Red;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HUDPackage.CrosshairsColor = FLinearColor::White;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TraceHitResult.bBlockingHit) TraceHitResult.ImpactPoint = End;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UCombatComponent::SetHUDCrosshairs(float DeltaTime)
|
void UCombatComponent::SetHUDCrosshairs(float DeltaTime)
|
||||||
{
|
{
|
||||||
if (Character == nullptr || Character->Controller == nullptr) return;
|
if (Character == nullptr || Character->Controller == nullptr) return;
|
||||||
|
@ -80,22 +348,22 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime)
|
||||||
HUDPackage.CrosshairsCenter = EquippedWeapon->CrosshairsCenter;
|
HUDPackage.CrosshairsCenter = EquippedWeapon->CrosshairsCenter;
|
||||||
HUDPackage.CrosshairsLeft = EquippedWeapon->CrosshairsLeft;
|
HUDPackage.CrosshairsLeft = EquippedWeapon->CrosshairsLeft;
|
||||||
HUDPackage.CrosshairsRight = EquippedWeapon->CrosshairsRight;
|
HUDPackage.CrosshairsRight = EquippedWeapon->CrosshairsRight;
|
||||||
HUDPackage.CrosshairsTop = EquippedWeapon->CrosshairsTop;
|
|
||||||
HUDPackage.CrosshairsBottom = EquippedWeapon->CrosshairsBottom;
|
HUDPackage.CrosshairsBottom = EquippedWeapon->CrosshairsBottom;
|
||||||
|
HUDPackage.CrosshairsTop = EquippedWeapon->CrosshairsTop;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HUDPackage.CrosshairsCenter = nullptr;
|
HUDPackage.CrosshairsCenter = nullptr;
|
||||||
HUDPackage.CrosshairsLeft = nullptr;
|
HUDPackage.CrosshairsLeft = nullptr;
|
||||||
HUDPackage.CrosshairsRight = nullptr;
|
HUDPackage.CrosshairsRight = nullptr;
|
||||||
HUDPackage.CrosshairsTop = nullptr;
|
|
||||||
HUDPackage.CrosshairsBottom = nullptr;
|
HUDPackage.CrosshairsBottom = nullptr;
|
||||||
|
HUDPackage.CrosshairsTop = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate crosshair spread
|
// Calculate crosshair spread
|
||||||
// Velocity [0, 600] -> Spread [0, 1]
|
|
||||||
const FVector2D WalkSpeedRange(0.f, Character->GetCharacterMovement()->MaxWalkSpeed);
|
// [0, 600] -> [0, 1]
|
||||||
const FVector2D VelocityMultiplierRange(0.f, 1.f);
|
FVector2D WalkSpeedRange(0.f, Character->GetCharacterMovement()->MaxWalkSpeed);
|
||||||
|
FVector2D VelocityMultiplierRange(0.f, 1.f);
|
||||||
FVector Velocity = Character->GetVelocity();
|
FVector Velocity = Character->GetVelocity();
|
||||||
Velocity.Z = 0.f;
|
Velocity.Z = 0.f;
|
||||||
|
|
||||||
|
@ -170,59 +438,9 @@ void UCombatComponent::ServerSetAiming_Implementation(bool bIsAiming)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::Fire()
|
|
||||||
{
|
|
||||||
if (CanFire())
|
|
||||||
{
|
|
||||||
bCanFire = false;
|
|
||||||
ServerFire(HitTarget);
|
|
||||||
|
|
||||||
if (EquippedWeapon)
|
|
||||||
{
|
|
||||||
CrosshairShootingFactor = 0.75f;
|
|
||||||
}
|
|
||||||
|
|
||||||
StartFireTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::FireButtonPressed(bool bPressed)
|
|
||||||
{
|
|
||||||
bFireButtonPressed = bPressed;
|
|
||||||
|
|
||||||
if (bFireButtonPressed && EquippedWeapon)
|
|
||||||
{
|
|
||||||
Fire();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::StartFireTimer()
|
|
||||||
{
|
|
||||||
if (EquippedWeapon == nullptr || Character == nullptr) return;
|
|
||||||
|
|
||||||
Character->GetWorldTimerManager().SetTimer(FireTimer, this, &UCombatComponent::FireTimerFinished, EquippedWeapon->FireDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::FireTimerFinished()
|
|
||||||
{
|
|
||||||
if (EquippedWeapon == nullptr) return;
|
|
||||||
|
|
||||||
bCanFire = true;
|
|
||||||
if (bFireButtonPressed && EquippedWeapon->bAutomatic)
|
|
||||||
{
|
|
||||||
Fire();
|
|
||||||
}
|
|
||||||
if (EquippedWeapon->IsEmpty())
|
|
||||||
{
|
|
||||||
Reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UCombatComponent::CanFire()
|
bool UCombatComponent::CanFire()
|
||||||
{
|
{
|
||||||
if (EquippedWeapon == nullptr) return false;
|
if (EquippedWeapon == nullptr) return false;
|
||||||
|
|
||||||
return !EquippedWeapon->IsEmpty() && bCanFire && CombatState == ECombatState::ECS_Unoccupied;
|
return !EquippedWeapon->IsEmpty() && bCanFire && CombatState == ECombatState::ECS_Unoccupied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,212 +457,3 @@ void UCombatComponent::InitializeCarriedAmmo()
|
||||||
{
|
{
|
||||||
CarriedAmmoMap.Emplace(EWeaponType::EWT_AssaultRifle, StartingARAmmo);
|
CarriedAmmoMap.Emplace(EWeaponType::EWT_AssaultRifle, StartingARAmmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
|
|
||||||
{
|
|
||||||
MulticastFire(TraceHitTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
|
|
||||||
{
|
|
||||||
if (EquippedWeapon == nullptr) return;
|
|
||||||
if (Character && CombatState == ECombatState::ECS_Unoccupied)
|
|
||||||
{
|
|
||||||
Character->PlayFireMontage(bAiming);
|
|
||||||
EquippedWeapon->Fire(TraceHitTarget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
|
|
||||||
{
|
|
||||||
FVector2d ViewPortSize;
|
|
||||||
if (GEngine && GEngine->GameViewport)
|
|
||||||
{
|
|
||||||
GEngine->GameViewport->GetViewportSize(ViewPortSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
FVector2d CrosshairLocation(ViewPortSize.X / 2.f, ViewPortSize.Y / 2.0f);
|
|
||||||
FVector CrosshairWorldPosition;
|
|
||||||
FVector CrosshairWorldDirection;
|
|
||||||
bool bScreenToWorld = UGameplayStatics::DeprojectScreenToWorld(
|
|
||||||
UGameplayStatics::GetPlayerController(this, 0),
|
|
||||||
CrosshairLocation,
|
|
||||||
CrosshairWorldPosition,
|
|
||||||
CrosshairWorldDirection
|
|
||||||
);
|
|
||||||
|
|
||||||
if (bScreenToWorld)
|
|
||||||
{
|
|
||||||
FVector Start = CrosshairWorldPosition;
|
|
||||||
if (Character)
|
|
||||||
{
|
|
||||||
float DistanceToCharacter = (Character->GetActorLocation() - Start).Size();
|
|
||||||
Start += CrosshairWorldDirection * (DistanceToCharacter + 60.f);
|
|
||||||
}
|
|
||||||
FVector End = Start + CrosshairWorldDirection * TRACE_LENGTH;
|
|
||||||
|
|
||||||
GetWorld()->LineTraceSingleByChannel(
|
|
||||||
TraceHitResult,
|
|
||||||
Start,
|
|
||||||
End,
|
|
||||||
ECollisionChannel::ECC_Visibility
|
|
||||||
);
|
|
||||||
if (TraceHitResult.GetActor() && TraceHitResult.GetActor()->Implements<UInteractWithCrosshairInterface>())
|
|
||||||
{
|
|
||||||
HUDPackage.CrosshairColor = FLinearColor::Red;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HUDPackage.CrosshairColor = FLinearColor::White;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TraceHitResult.bBlockingHit) TraceHitResult.ImpactPoint = End;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip)
|
|
||||||
{
|
|
||||||
if (Character == nullptr || WeaponToEquip == nullptr) return;
|
|
||||||
if (EquippedWeapon)
|
|
||||||
{
|
|
||||||
EquippedWeapon->Dropped();
|
|
||||||
}
|
|
||||||
EquippedWeapon = WeaponToEquip;
|
|
||||||
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
|
||||||
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));
|
|
||||||
if (HandSocket)
|
|
||||||
{
|
|
||||||
HandSocket->AttachActor(EquippedWeapon, Character->GetMesh());
|
|
||||||
}
|
|
||||||
EquippedWeapon->SetOwner(Character);
|
|
||||||
EquippedWeapon->SetHUDAmmo();
|
|
||||||
|
|
||||||
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
|
||||||
{
|
|
||||||
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
|
||||||
if (Controller)
|
|
||||||
{
|
|
||||||
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EquippedWeapon->EquipSound)
|
|
||||||
{
|
|
||||||
UGameplayStatics::PlaySoundAtLocation(this, EquippedWeapon->EquipSound, Character->GetActorLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EquippedWeapon->IsEmpty())
|
|
||||||
{
|
|
||||||
Reload();
|
|
||||||
}
|
|
||||||
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
|
|
||||||
Character->bUseControllerRotationYaw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::Reload()
|
|
||||||
{
|
|
||||||
if (CarriedAmmo > 0 && CombatState != ECombatState::ECS_Reloading)
|
|
||||||
{
|
|
||||||
ServerReload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::FinishedReloading()
|
|
||||||
{
|
|
||||||
if (Character == nullptr) return;
|
|
||||||
if (Character->HasAuthority())
|
|
||||||
{
|
|
||||||
CombatState = ECombatState::ECS_Unoccupied;
|
|
||||||
UpdateAmmoValues();
|
|
||||||
}
|
|
||||||
if (bFireButtonPressed)
|
|
||||||
{
|
|
||||||
Fire();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::UpdateAmmoValues()
|
|
||||||
{
|
|
||||||
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
|
||||||
const int32 ReloadAmount = AmountToReload();
|
|
||||||
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
|
||||||
{
|
|
||||||
CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= ReloadAmount;
|
|
||||||
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
|
||||||
}
|
|
||||||
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
|
||||||
if (Controller)
|
|
||||||
{
|
|
||||||
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
|
||||||
}
|
|
||||||
EquippedWeapon->AddAmmo(-ReloadAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::ServerReload_Implementation()
|
|
||||||
{
|
|
||||||
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
|
||||||
|
|
||||||
// return if weapon mag is at max capacity
|
|
||||||
if (EquippedWeapon->GetAmmo() == EquippedWeapon->GetMagCapacity()) return;
|
|
||||||
|
|
||||||
CombatState = ECombatState::ECS_Reloading;
|
|
||||||
HandleReload();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::OnRep_CombatState()
|
|
||||||
{
|
|
||||||
switch (CombatState)
|
|
||||||
{
|
|
||||||
case ECombatState::ECS_Reloading:
|
|
||||||
HandleReload();
|
|
||||||
break;
|
|
||||||
case ECombatState::ECS_Unoccupied:
|
|
||||||
if (bFireButtonPressed)
|
|
||||||
{
|
|
||||||
Fire();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::HandleReload()
|
|
||||||
{
|
|
||||||
Character->PlayReloadMontage();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 UCombatComponent::AmountToReload()
|
|
||||||
{
|
|
||||||
if (EquippedWeapon == nullptr) return 0;
|
|
||||||
|
|
||||||
const int32 RoomInMag = EquippedWeapon->GetMagCapacity() - EquippedWeapon->GetAmmo();
|
|
||||||
|
|
||||||
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
|
||||||
{
|
|
||||||
const int32 AmountCarried = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
|
||||||
const int32 Least = FMath::Min(RoomInMag, AmountCarried);
|
|
||||||
return FMath::Clamp(RoomInMag, 0, Least);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::OnRep_EquippedWeapon()
|
|
||||||
{
|
|
||||||
if (EquippedWeapon && Character)
|
|
||||||
{
|
|
||||||
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
|
||||||
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));
|
|
||||||
if (HandSocket)
|
|
||||||
{
|
|
||||||
HandSocket->AttachActor(EquippedWeapon, Character->GetMesh());
|
|
||||||
}
|
|
||||||
if (EquippedWeapon->EquipSound)
|
|
||||||
{
|
|
||||||
UGameplayStatics::PlaySoundAtLocation(this, EquippedWeapon->EquipSound, Character->GetActorLocation());
|
|
||||||
}
|
|
||||||
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
|
|
||||||
Character->bUseControllerRotationYaw = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,13 +2,11 @@
|
||||||
|
|
||||||
|
|
||||||
#include "BlasterGameMode.h"
|
#include "BlasterGameMode.h"
|
||||||
|
|
||||||
#include "Blaster/Character/BlasterCharacter.h"
|
#include "Blaster/Character/BlasterCharacter.h"
|
||||||
#include "Blaster/PlayerController/BlasterPlayerController.h"
|
#include "Blaster/PlayerController/BlasterPlayerController.h"
|
||||||
#include "Blaster/PlayerState/BlasterPlayerState.h"
|
|
||||||
#include "GameFramework/PlayerStart.h"
|
|
||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
#include "GameFramework/PlayerStart.h"
|
||||||
|
#include "Blaster/PlayerState/BlasterPlayerState.h"
|
||||||
|
|
||||||
namespace MatchState
|
namespace MatchState
|
||||||
{
|
{
|
||||||
|
@ -27,30 +25,30 @@ void ABlasterGameMode::BeginPlay()
|
||||||
LevelStartingTime = GetWorld()->GetTimeSeconds();
|
LevelStartingTime = GetWorld()->GetTimeSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterGameMode::Tick(float DeltaSeconds)
|
void ABlasterGameMode::Tick(float DeltaTime)
|
||||||
{
|
{
|
||||||
Super::Tick(DeltaSeconds);
|
Super::Tick(DeltaTime);
|
||||||
|
|
||||||
if (MatchState == MatchState::WaitingToStart)
|
if (MatchState == MatchState::WaitingToStart)
|
||||||
{
|
{
|
||||||
CountDownTime = WarmupTime - GetWorld()->GetTimeSeconds() + LevelStartingTime;
|
CountdownTime = WarmupTime - GetWorld()->GetTimeSeconds() + LevelStartingTime;
|
||||||
if (CountDownTime <= 0.f)
|
if (CountdownTime <= 0.f)
|
||||||
{
|
{
|
||||||
StartMatch();
|
StartMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (MatchState == MatchState::InProgress)
|
else if (MatchState == MatchState::InProgress)
|
||||||
{
|
{
|
||||||
CountDownTime = WarmupTime + MatchTime - GetWorld()->GetTimeSeconds() + LevelStartingTime;
|
CountdownTime = WarmupTime + MatchTime - GetWorld()->GetTimeSeconds() + LevelStartingTime;
|
||||||
if (CountDownTime <= 0.f)
|
if (CountdownTime <= 0.f)
|
||||||
{
|
{
|
||||||
SetMatchState(MatchState::Cooldown);
|
SetMatchState(MatchState::Cooldown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (MatchState == MatchState::Cooldown)
|
else if (MatchState == MatchState::Cooldown)
|
||||||
{
|
{
|
||||||
CountDownTime = CooldownTime + WarmupTime + MatchTime - GetWorld()->GetTimeSeconds() + LevelStartingTime;
|
CountdownTime = CooldownTime + WarmupTime + MatchTime - GetWorld()->GetTimeSeconds() + LevelStartingTime;
|
||||||
if (CountDownTime <= 0.f)
|
if (CountdownTime <= 0.f)
|
||||||
{
|
{
|
||||||
RestartGame();
|
RestartGame();
|
||||||
}
|
}
|
||||||
|
@ -61,29 +59,31 @@ void ABlasterGameMode::OnMatchStateSet()
|
||||||
{
|
{
|
||||||
Super::OnMatchStateSet();
|
Super::OnMatchStateSet();
|
||||||
|
|
||||||
for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
|
for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; ++It)
|
||||||
{
|
{
|
||||||
ABlasterPlayerController* PlayerController = Cast<ABlasterPlayerController>(*Iterator);
|
ABlasterPlayerController* BlasterPlayer = Cast<ABlasterPlayerController>(*It);
|
||||||
if (PlayerController)
|
if (BlasterPlayer)
|
||||||
{
|
{
|
||||||
PlayerController->OnMatchStateSet(MatchState);
|
BlasterPlayer->OnMatchStateSet(MatchState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterGameMode::PlayerEliminated(ABlasterCharacter* EliminatedCharacter, ABlasterPlayerController* VictimController,
|
void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedCharacter, ABlasterPlayerController* VictimController,
|
||||||
ABlasterPlayerController* AttackerController)
|
ABlasterPlayerController* AttackerController)
|
||||||
{
|
{
|
||||||
|
if (AttackerController == nullptr || AttackerController->PlayerState == nullptr) return;
|
||||||
|
if (VictimController == nullptr || VictimController->PlayerState == nullptr) return;
|
||||||
ABlasterPlayerState* AttackerPlayerState = AttackerController ? Cast<ABlasterPlayerState>(AttackerController->PlayerState) : nullptr;
|
ABlasterPlayerState* AttackerPlayerState = AttackerController ? Cast<ABlasterPlayerState>(AttackerController->PlayerState) : nullptr;
|
||||||
ABlasterPlayerState* VictimPlayerState = VictimController ? Cast<ABlasterPlayerState>(VictimController->PlayerState) : nullptr;
|
ABlasterPlayerState* VictimPlayerState = VictimController ? Cast<ABlasterPlayerState>(VictimController->PlayerState) : nullptr;
|
||||||
|
|
||||||
if (AttackerPlayerState && AttackerPlayerState != VictimPlayerState)
|
if (AttackerPlayerState && AttackerPlayerState != VictimPlayerState)
|
||||||
{
|
{
|
||||||
AttackerPlayerState->IncreaseScore(1.f);
|
AttackerPlayerState->AddToScore(1.f);
|
||||||
}
|
}
|
||||||
if (VictimPlayerState)
|
if (VictimPlayerState)
|
||||||
{
|
{
|
||||||
VictimPlayerState->IncreaseDefeats(1);
|
VictimPlayerState->AddToDefeats(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EliminatedCharacter)
|
if (EliminatedCharacter)
|
||||||
|
@ -99,12 +99,11 @@ void ABlasterGameMode::RequestRespawn(ACharacter* EliminatedCharacter, AControll
|
||||||
EliminatedCharacter->Reset();
|
EliminatedCharacter->Reset();
|
||||||
EliminatedCharacter->Destroy();
|
EliminatedCharacter->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EliminatedController)
|
if (EliminatedController)
|
||||||
{
|
{
|
||||||
TArray<AActor*> PlayerStarts;
|
TArray<AActor*> PlayerStarts;
|
||||||
UGameplayStatics::GetAllActorsOfClass(this, APlayerStart::StaticClass(), PlayerStarts);
|
UGameplayStatics::GetAllActorsOfClass(this, APlayerStart::StaticClass(), PlayerStarts);
|
||||||
const int32 Selection = FMath::RandRange(0, PlayerStarts.Num() - 1);
|
int32 Selection = FMath::RandRange(0, PlayerStarts.Num() - 1);
|
||||||
RestartPlayerAtPlayerStart(EliminatedController, PlayerStarts[Selection]);
|
RestartPlayerAtPlayerStart(EliminatedController, PlayerStarts[Selection]);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ class BLASTER_API ABlasterGameMode : public AGameMode
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ABlasterGameMode();
|
ABlasterGameMode();
|
||||||
virtual void Tick(float DeltaSeconds) override;
|
virtual void Tick(float DeltaTime) override;
|
||||||
virtual void PlayerEliminated(class ABlasterCharacter* EliminatedCharacter, class ABlasterPlayerController* VictimController,
|
virtual void PlayerEliminated(class ABlasterCharacter* EliminatedCharacter, class ABlasterPlayerController* VictimController,
|
||||||
class ABlasterPlayerController* AttackerController);
|
class ABlasterPlayerController* AttackerController);
|
||||||
virtual void RequestRespawn(ACharacter* EliminatedCharacter, AController* EliminatedController);
|
virtual void RequestRespawn(ACharacter* EliminatedCharacter, AController* EliminatedController);
|
||||||
|
@ -43,8 +43,8 @@ protected:
|
||||||
virtual void OnMatchStateSet() override;
|
virtual void OnMatchStateSet() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float CountDownTime = 0.f;
|
float CountdownTime = 0.f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FORCEINLINE float GetCountdownTime() const { return CountDownTime; }
|
FORCEINLINE float GetCountdownTime() const { return CountdownTime; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,16 +13,15 @@ UCLASS()
|
||||||
class BLASTER_API UAnnouncement : public UUserWidget
|
class BLASTER_API UAnnouncement : public UUserWidget
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
UPROPERTY(meta = (BindWidget))
|
||||||
class UTextBlock* AnnouncementText;
|
class UTextBlock* WarmupTime;
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
UPROPERTY(meta = (BindWidget))
|
||||||
UTextBlock* CountdownText;
|
UTextBlock* AnnouncementText;
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
UPROPERTY(meta = (BindWidget))
|
||||||
UTextBlock* AnnouncementMessage;
|
UTextBlock* InfoText;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,7 @@ void ABlasterHUD::AddCharacterOverlay()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterHUD::AddAnnouncementOverlay()
|
void ABlasterHUD::AddAnnouncement()
|
||||||
{
|
{
|
||||||
APlayerController* PlayerController = GetOwningPlayerController();
|
APlayerController* PlayerController = GetOwningPlayerController();
|
||||||
if (PlayerController && AnnouncementClass)
|
if (PlayerController && AnnouncementClass)
|
||||||
|
@ -46,27 +46,27 @@ void ABlasterHUD::DrawHUD()
|
||||||
if (HUDPackage.CrosshairsCenter)
|
if (HUDPackage.CrosshairsCenter)
|
||||||
{
|
{
|
||||||
const FVector2D Spread(0.f, 0.f);
|
const FVector2D Spread(0.f, 0.f);
|
||||||
DrawCrosshair(HUDPackage.CrosshairsCenter, ViewportCenter, Spread, HUDPackage.CrosshairColor);
|
DrawCrosshair(HUDPackage.CrosshairsCenter, ViewportCenter, Spread, HUDPackage.CrosshairsColor);
|
||||||
}
|
}
|
||||||
if (HUDPackage.CrosshairsLeft)
|
if (HUDPackage.CrosshairsLeft)
|
||||||
{
|
{
|
||||||
const FVector2D Spread(-SpreadScaled, 0.f);
|
const FVector2D Spread(-SpreadScaled, 0.f);
|
||||||
DrawCrosshair(HUDPackage.CrosshairsLeft, ViewportCenter, Spread, HUDPackage.CrosshairColor);
|
DrawCrosshair(HUDPackage.CrosshairsLeft, ViewportCenter, Spread, HUDPackage.CrosshairsColor);
|
||||||
}
|
}
|
||||||
if (HUDPackage.CrosshairsRight)
|
if (HUDPackage.CrosshairsRight)
|
||||||
{
|
{
|
||||||
const FVector2D Spread(SpreadScaled, 0.f);
|
const FVector2D Spread(SpreadScaled, 0.f);
|
||||||
DrawCrosshair(HUDPackage.CrosshairsRight, ViewportCenter, Spread, HUDPackage.CrosshairColor);
|
DrawCrosshair(HUDPackage.CrosshairsRight, ViewportCenter, Spread, HUDPackage.CrosshairsColor);
|
||||||
}
|
}
|
||||||
if (HUDPackage.CrosshairsTop)
|
if (HUDPackage.CrosshairsTop)
|
||||||
{
|
{
|
||||||
const FVector2D Spread(0.f, -SpreadScaled);
|
const FVector2D Spread(0.f, -SpreadScaled);
|
||||||
DrawCrosshair(HUDPackage.CrosshairsTop, ViewportCenter, Spread, HUDPackage.CrosshairColor);
|
DrawCrosshair(HUDPackage.CrosshairsTop, ViewportCenter, Spread, HUDPackage.CrosshairsColor);
|
||||||
}
|
}
|
||||||
if (HUDPackage.CrosshairsBottom)
|
if (HUDPackage.CrosshairsBottom)
|
||||||
{
|
{
|
||||||
const FVector2D Spread(0.f, SpreadScaled);
|
const FVector2D Spread(0.f, SpreadScaled);
|
||||||
DrawCrosshair(HUDPackage.CrosshairsBottom, ViewportCenter, Spread, HUDPackage.CrosshairColor);
|
DrawCrosshair(HUDPackage.CrosshairsBottom, ViewportCenter, Spread, HUDPackage.CrosshairsColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
UTexture2D* CrosshairsTop;
|
UTexture2D* CrosshairsTop;
|
||||||
UTexture2D* CrosshairsBottom;
|
UTexture2D* CrosshairsBottom;
|
||||||
float CrosshairSpread;
|
float CrosshairSpread;
|
||||||
FLinearColor CrosshairColor;
|
FLinearColor CrosshairsColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +32,7 @@ class BLASTER_API ABlasterHUD : public AHUD
|
||||||
public:
|
public:
|
||||||
virtual void DrawHUD() override;
|
virtual void DrawHUD() override;
|
||||||
void AddCharacterOverlay();
|
void AddCharacterOverlay();
|
||||||
void AddAnnouncementOverlay();
|
void AddAnnouncement();
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, Category = "Player Stats")
|
UPROPERTY(EditAnywhere, Category = "Player Stats")
|
||||||
TSubclassOf<class UUserWidget> CharacterOverlayClass;
|
TSubclassOf<class UUserWidget> CharacterOverlayClass;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
#include "InteractWithCrosshairInterface.h"
|
#include "InteractWithCrosshairsInterface.h"
|
||||||
|
|
||||||
// Add default functionality here for any IInteractWithCrosshairInterface functions that are not pure virtual.
|
// Add default functionality here for any IInteractWithCrosshairInterface functions that are not pure virtual.
|
|
@ -4,11 +4,11 @@
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "UObject/Interface.h"
|
#include "UObject/Interface.h"
|
||||||
#include "InteractWithCrosshairInterface.generated.h"
|
#include "InteractWithCrosshairsInterface.generated.h"
|
||||||
|
|
||||||
// This class does not need to be modified.
|
// This class does not need to be modified.
|
||||||
UINTERFACE(MinimalAPI)
|
UINTERFACE(MinimalAPI)
|
||||||
class UInteractWithCrosshairInterface : public UInterface
|
class UInteractWithCrosshairsInterface : public UInterface
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@ class UInteractWithCrosshairInterface : public UInterface
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class BLASTER_API IInteractWithCrosshairInterface
|
class BLASTER_API IInteractWithCrosshairsInterface
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
|
|
||||||
#include "BlasterPlayerController.h"
|
#include "BlasterPlayerController.h"
|
||||||
|
|
||||||
#include "Blaster/Character/BlasterCharacter.h"
|
#include "Blaster/Character/BlasterCharacter.h"
|
||||||
#include "Blaster/Components/CombatComponent.h"
|
#include "Blaster/Components/CombatComponent.h"
|
||||||
#include "Blaster/GameMode/BlasterGameMode.h"
|
#include "Blaster/GameMode/BlasterGameMode.h"
|
||||||
|
@ -31,38 +30,18 @@ void ABlasterPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProper
|
||||||
DOREPLIFETIME(ABlasterPlayerController, MatchState);
|
DOREPLIFETIME(ABlasterPlayerController, MatchState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::Tick(float DeltaSeconds)
|
void ABlasterPlayerController::Tick(float DeltaTime)
|
||||||
{
|
{
|
||||||
Super::Tick(DeltaSeconds);
|
Super::Tick(DeltaTime);
|
||||||
|
|
||||||
SetHUDTime();
|
SetHUDTime();
|
||||||
CheckTimeSync(DeltaSeconds);
|
CheckTimeSync(DeltaTime);
|
||||||
PollInit();
|
PollInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::OnPossess(APawn* InPawn)
|
void ABlasterPlayerController::CheckTimeSync(float DeltaTime)
|
||||||
{
|
{
|
||||||
Super::OnPossess(InPawn);
|
TimeSyncRunningTime += DeltaTime;
|
||||||
|
|
||||||
if (const ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(InPawn))
|
|
||||||
{
|
|
||||||
SetHUDHealth(BlasterCharacter->GetHealth(), BlasterCharacter->GetMaxHealth());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::ReceivedPlayer()
|
|
||||||
{
|
|
||||||
Super::ReceivedPlayer();
|
|
||||||
|
|
||||||
if (IsLocalController())
|
|
||||||
{
|
|
||||||
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::CheckTimeSync(float DeltaSeconds)
|
|
||||||
{
|
|
||||||
TimeSyncRunningTime += DeltaSeconds;
|
|
||||||
if (IsLocalController() && TimeSyncRunningTime > TimeSyncFrequency)
|
if (IsLocalController() && TimeSyncRunningTime > TimeSyncFrequency)
|
||||||
{
|
{
|
||||||
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
|
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
|
||||||
|
@ -70,119 +49,172 @@ void ABlasterPlayerController::CheckTimeSync(float DeltaSeconds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float ABlasterPlayerController::GetServerTime()
|
|
||||||
{
|
|
||||||
if (HasAuthority()) return GetWorld()->GetTimeSeconds();
|
|
||||||
return GetWorld()->GetTimeSeconds() + ClientServerDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::HandleMatchHasStarted()
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
if (BlasterHUD)
|
|
||||||
{
|
|
||||||
BlasterHUD->AddCharacterOverlay();
|
|
||||||
if (BlasterHUD->Announcement)
|
|
||||||
{
|
|
||||||
BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Hidden);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::HandleCooldown()
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
if (BlasterHUD)
|
|
||||||
{
|
|
||||||
BlasterHUD->CharacterOverlay->RemoveFromParent();
|
|
||||||
bool bHUDValid =
|
|
||||||
BlasterHUD->Announcement &&
|
|
||||||
BlasterHUD->Announcement->AnnouncementText &&
|
|
||||||
BlasterHUD->Announcement->AnnouncementMessage;
|
|
||||||
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
const FString AnnouncementText("New match starts in:");
|
|
||||||
BlasterHUD->Announcement->AnnouncementText->SetText(FText::FromString(AnnouncementText));
|
|
||||||
BlasterHUD->Announcement->AnnouncementMessage->SetText(FText());
|
|
||||||
BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(GetPawn());
|
|
||||||
if (BlasterCharacter && BlasterCharacter->GetCombat())
|
|
||||||
{
|
|
||||||
BlasterCharacter->bDisableGameplay = true;
|
|
||||||
BlasterCharacter->GetCombat()->FireButtonPressed(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::OnMatchStateSet(FName State)
|
|
||||||
{
|
|
||||||
MatchState = State;
|
|
||||||
|
|
||||||
if (MatchState == MatchState::InProgress)
|
|
||||||
{
|
|
||||||
HandleMatchHasStarted();
|
|
||||||
}
|
|
||||||
else if (MatchState == MatchState::Cooldown)
|
|
||||||
{
|
|
||||||
HandleCooldown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::OnRep_MatchState()
|
|
||||||
{
|
|
||||||
if (MatchState == MatchState::InProgress)
|
|
||||||
{
|
|
||||||
HandleMatchHasStarted();
|
|
||||||
}
|
|
||||||
else if (MatchState == MatchState::Cooldown)
|
|
||||||
{
|
|
||||||
HandleCooldown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::ServerCheckMatchState_Implementation()
|
void ABlasterPlayerController::ServerCheckMatchState_Implementation()
|
||||||
{
|
{
|
||||||
ABlasterGameMode* GameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
|
ABlasterGameMode* GameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
|
||||||
if (GameMode)
|
if (GameMode)
|
||||||
{
|
{
|
||||||
LevelStartingTime = GameMode->LevelStartingTime;
|
|
||||||
WarmupTime = GameMode->WarmupTime;
|
WarmupTime = GameMode->WarmupTime;
|
||||||
MatchTime = GameMode->MatchTime;
|
MatchTime = GameMode->MatchTime;
|
||||||
CooldownTime = GameMode->CooldownTime;
|
CooldownTime = GameMode->CooldownTime;
|
||||||
|
LevelStartingTime = GameMode->LevelStartingTime;
|
||||||
MatchState = GameMode->GetMatchState();
|
MatchState = GameMode->GetMatchState();
|
||||||
ClientJoinMidGame(MatchState, WarmupTime, MatchTime, CooldownTime, LevelStartingTime);
|
ClientJoinMidgame(MatchState, WarmupTime, MatchTime, CooldownTime, LevelStartingTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::ClientJoinMidGame_Implementation(FName StateOfMatch, float Warmup, float Match, float Cooldown, float StartingTime)
|
void ABlasterPlayerController::ClientJoinMidgame_Implementation(FName StateOfMatch, float Warmup, float Match, float Cooldown, float StartingTime)
|
||||||
{
|
{
|
||||||
LevelStartingTime = StartingTime;
|
|
||||||
WarmupTime = Warmup;
|
WarmupTime = Warmup;
|
||||||
MatchTime = Match;
|
MatchTime = Match;
|
||||||
CooldownTime = Cooldown;
|
CooldownTime = Cooldown;
|
||||||
|
LevelStartingTime = StartingTime;
|
||||||
MatchState = StateOfMatch;
|
MatchState = StateOfMatch;
|
||||||
OnMatchStateSet(MatchState);
|
OnMatchStateSet(MatchState);
|
||||||
|
|
||||||
if (BlasterHUD && MatchState == MatchState::WaitingToStart)
|
if (BlasterHUD && MatchState == MatchState::WaitingToStart)
|
||||||
{
|
{
|
||||||
BlasterHUD->AddAnnouncementOverlay();
|
BlasterHUD->AddAnnouncement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest)
|
void ABlasterPlayerController::OnPossess(APawn* InPawn)
|
||||||
{
|
{
|
||||||
const float ServerTimeOfReceipt = GetWorld()->GetTimeSeconds();
|
Super::OnPossess(InPawn);
|
||||||
ClientReportServerTime(TimeOfClientRequest, ServerTimeOfReceipt);
|
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(InPawn);
|
||||||
|
if (BlasterCharacter)
|
||||||
|
{
|
||||||
|
SetHUDHealth(BlasterCharacter->GetHealth(), BlasterCharacter->GetMaxHealth());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::ClientReportServerTime_Implementation(float TimeOfClientRequest, float TimeServerReceivedClientRequest)
|
void ABlasterPlayerController::SetHUDHealth(float Health, float MaxHealth)
|
||||||
{
|
{
|
||||||
const float RoundTripTime = GetWorld()->GetTimeSeconds() - TimeOfClientRequest;
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
const float CurrentServerTime = TimeServerReceivedClientRequest + (0.5f * RoundTripTime);
|
bool bHUDValid = BlasterHUD &&
|
||||||
ClientServerDelta = CurrentServerTime - GetWorld()->GetTimeSeconds();
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->HealthBar &&
|
||||||
|
BlasterHUD->CharacterOverlay->HealthText;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
const float HealthPercent = Health / MaxHealth;
|
||||||
|
BlasterHUD->CharacterOverlay->HealthBar->SetPercent(HealthPercent);
|
||||||
|
FString HealthText = FString::Printf(TEXT("%d/%d"), FMath::CeilToInt(Health), FMath::CeilToInt(MaxHealth));
|
||||||
|
BlasterHUD->CharacterOverlay->HealthText->SetText(FText::FromString(HealthText));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bInitializeCharacterOverlay = true;
|
||||||
|
HUDHealth = Health;
|
||||||
|
HUDMaxHealth = MaxHealth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::SetHUDScore(float Score)
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->ScoreValue;
|
||||||
|
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
FString ScoreText = FString::Printf(TEXT("%d"), FMath::FloorToInt(Score));
|
||||||
|
BlasterHUD->CharacterOverlay->ScoreValue->SetText(FText::FromString(ScoreText));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bInitializeCharacterOverlay = true;
|
||||||
|
HUDScore = Score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::SetHUDDefeats(int32 Defeats)
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->DefeatsValue;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
FString DefeatsText = FString::Printf(TEXT("%d"), Defeats);
|
||||||
|
BlasterHUD->CharacterOverlay->DefeatsValue->SetText(FText::FromString(DefeatsText));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bInitializeCharacterOverlay = true;
|
||||||
|
HUDDefeats = Defeats;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo)
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->WeaponAmmoValue;
|
||||||
|
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
FString AmmoText = FString::Printf(TEXT("%d"), Ammo);
|
||||||
|
BlasterHUD->CharacterOverlay->WeaponAmmoValue->SetText(FText::FromString(AmmoText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::SetHUDCarriedAmmo(int32 Ammo)
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->CarriedAmmoValue;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
FString AmmoText = FString::Printf(TEXT("%d"), Ammo);
|
||||||
|
BlasterHUD->CharacterOverlay->CarriedAmmoValue->SetText(FText::FromString(AmmoText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::SetHUDMatchCountdown(float CountdownTime)
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->MatchCountdownText;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
if (CountdownTime < 0.f)
|
||||||
|
{
|
||||||
|
BlasterHUD->CharacterOverlay->MatchCountdownText->SetText(FText());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 Minutes = FMath::FloorToInt(CountdownTime / 60.f);
|
||||||
|
int32 Seconds = CountdownTime - Minutes * 60;
|
||||||
|
|
||||||
|
FString CountdownText = FString::Printf(TEXT("%02d:%02d"), Minutes, Seconds);
|
||||||
|
BlasterHUD->CharacterOverlay->MatchCountdownText->SetText(FText::FromString(CountdownText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::SetHUDAnnouncementCountdown(float CountdownTime)
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->Announcement &&
|
||||||
|
BlasterHUD->Announcement->WarmupTime;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
if (CountdownTime < 0.f)
|
||||||
|
{
|
||||||
|
BlasterHUD->Announcement->WarmupTime->SetText(FText());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 Minutes = FMath::FloorToInt(CountdownTime / 60.f);
|
||||||
|
int32 Seconds = CountdownTime - Minutes * 60;
|
||||||
|
|
||||||
|
FString CountdownText = FString::Printf(TEXT("%02d:%02d"), Minutes, Seconds);
|
||||||
|
BlasterHUD->Announcement->WarmupTime->SetText(FText::FromString(CountdownText));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDTime()
|
void ABlasterPlayerController::SetHUDTime()
|
||||||
|
@ -225,142 +257,95 @@ void ABlasterPlayerController::PollInit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDHealth(float Health, float MaxHealth)
|
void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest)
|
||||||
|
{
|
||||||
|
float ServerTimeOfReceipt = GetWorld()->GetTimeSeconds();
|
||||||
|
ClientReportServerTime(TimeOfClientRequest, ServerTimeOfReceipt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::ClientReportServerTime_Implementation(float TimeOfClientRequest, float TimeServerReceivedClientRequest)
|
||||||
|
{
|
||||||
|
float RoundTripTime = GetWorld()->GetTimeSeconds() - TimeOfClientRequest;
|
||||||
|
float CurrentServerTime = TimeServerReceivedClientRequest + (0.5f * RoundTripTime);
|
||||||
|
ClientServerDelta = CurrentServerTime - GetWorld()->GetTimeSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
float ABlasterPlayerController::GetServerTime()
|
||||||
|
{
|
||||||
|
if (HasAuthority()) return GetWorld()->GetTimeSeconds();
|
||||||
|
return GetWorld()->GetTimeSeconds() + ClientServerDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::ReceivedPlayer()
|
||||||
|
{
|
||||||
|
Super::ReceivedPlayer();
|
||||||
|
if (IsLocalController())
|
||||||
|
{
|
||||||
|
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::OnMatchStateSet(FName State)
|
||||||
|
{
|
||||||
|
MatchState = State;
|
||||||
|
|
||||||
|
if (MatchState == MatchState::InProgress)
|
||||||
|
{
|
||||||
|
HandleMatchHasStarted();
|
||||||
|
}
|
||||||
|
else if (MatchState == MatchState::Cooldown)
|
||||||
|
{
|
||||||
|
HandleCooldown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::OnRep_MatchState()
|
||||||
|
{
|
||||||
|
if (MatchState == MatchState::InProgress)
|
||||||
|
{
|
||||||
|
HandleMatchHasStarted();
|
||||||
|
}
|
||||||
|
else if (MatchState == MatchState::Cooldown)
|
||||||
|
{
|
||||||
|
HandleCooldown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::HandleMatchHasStarted()
|
||||||
{
|
{
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
bool bHUDValid =
|
if (BlasterHUD)
|
||||||
BlasterHUD &&
|
{
|
||||||
BlasterHUD->CharacterOverlay &&
|
BlasterHUD->AddCharacterOverlay();
|
||||||
BlasterHUD->CharacterOverlay->HealthBar &&
|
if (BlasterHUD->Announcement)
|
||||||
BlasterHUD->CharacterOverlay->HealthText;
|
{
|
||||||
|
BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Hidden);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::HandleCooldown()
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
if (BlasterHUD)
|
||||||
|
{
|
||||||
|
BlasterHUD->CharacterOverlay->RemoveFromParent();
|
||||||
|
bool bHUDValid = BlasterHUD->Announcement &&
|
||||||
|
BlasterHUD->Announcement->AnnouncementText &&
|
||||||
|
BlasterHUD->Announcement->InfoText;
|
||||||
|
|
||||||
if (bHUDValid)
|
if (bHUDValid)
|
||||||
{
|
{
|
||||||
const float HealthPercent = Health / MaxHealth;
|
BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Visible);
|
||||||
BlasterHUD->CharacterOverlay->HealthBar->SetPercent(HealthPercent);
|
FString AnnouncementText("New match starts in:");
|
||||||
const FString HealthText = FString::Printf(TEXT("%d/%d"), FMath::CeilToInt(Health), FMath::CeilToInt(MaxHealth));
|
BlasterHUD->Announcement->AnnouncementText->SetText(FText::FromString(AnnouncementText));
|
||||||
BlasterHUD->CharacterOverlay->HealthText->SetText(FText::FromString(HealthText));
|
BlasterHUD->Announcement->InfoText->SetText(FText());
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(GetPawn());
|
||||||
|
if (BlasterCharacter && BlasterCharacter->GetCombat())
|
||||||
{
|
{
|
||||||
bInitializeCharacterOverlay = true;
|
BlasterCharacter->bDisableGameplay = true;
|
||||||
HUDHealth = Health;
|
BlasterCharacter->GetCombat()->FireButtonPressed(false);
|
||||||
HUDMaxHealth = MaxHealth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDScore(float Score)
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid =
|
|
||||||
BlasterHUD &&
|
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->ScoreValue;
|
|
||||||
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
const FString ScoreAmount = FString::Printf(TEXT("%d"), FMath::FloorToInt(Score));
|
|
||||||
BlasterHUD->CharacterOverlay->ScoreValue->SetText(FText::FromString(ScoreAmount));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bInitializeCharacterOverlay = true;
|
|
||||||
HUDScore = Score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDDefeats(int32 Defeats)
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid =
|
|
||||||
BlasterHUD &&
|
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->DefeatsValue;
|
|
||||||
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
const FString DefeatsAmount = FString::Printf(TEXT("%d"), Defeats);
|
|
||||||
BlasterHUD->CharacterOverlay->DefeatsValue->SetText(FText::FromString(DefeatsAmount));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bInitializeCharacterOverlay = true;
|
|
||||||
HUDDefeats = Defeats;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo)
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid =
|
|
||||||
BlasterHUD &&
|
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->WeaponAmmoValue;
|
|
||||||
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
const FString WeaponAmmoAmount = FString::Printf(TEXT("%d"), Ammo);
|
|
||||||
BlasterHUD->CharacterOverlay->WeaponAmmoValue->SetText(FText::FromString(WeaponAmmoAmount));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDCarriedAmmo(int32 Ammo)
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid =
|
|
||||||
BlasterHUD &&
|
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->CarriedAmmoValue;
|
|
||||||
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
const FString CarriedAmmoAmount = FString::Printf(TEXT("%d"), Ammo);
|
|
||||||
BlasterHUD->CharacterOverlay->CarriedAmmoValue->SetText(FText::FromString(CarriedAmmoAmount));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDMatchCountdown(float CountdownTime)
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid =
|
|
||||||
BlasterHUD &&
|
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->MatchCountdownText;
|
|
||||||
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
if (CountdownTime < 0.f)
|
|
||||||
{
|
|
||||||
BlasterHUD->CharacterOverlay->MatchCountdownText->SetText(FText());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const int32 Minutes = FMath::FloorToInt(CountdownTime / 60);
|
|
||||||
const int32 Seconds = CountdownTime - Minutes * 60;
|
|
||||||
|
|
||||||
const FString CountdownText = FString::Printf(TEXT("%02d:%02d"), Minutes, Seconds);
|
|
||||||
BlasterHUD->CharacterOverlay->MatchCountdownText->SetText(FText::FromString(CountdownText));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDAnnouncementCountdown(float CountdownTime)
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid =
|
|
||||||
BlasterHUD &&
|
|
||||||
BlasterHUD->Announcement &&
|
|
||||||
BlasterHUD->Announcement->CountdownText;
|
|
||||||
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
if (CountdownTime < 0.f)
|
|
||||||
{
|
|
||||||
BlasterHUD->Announcement->CountdownText->SetText(FText());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const int32 Minutes = FMath::FloorToInt(CountdownTime / 60);
|
|
||||||
const int32 Seconds = CountdownTime - Minutes * 60;
|
|
||||||
|
|
||||||
const FString CountdownText = FString::Printf(TEXT("%02d:%02d"), Minutes, Seconds);
|
|
||||||
BlasterHUD->Announcement->CountdownText->SetText(FText::FromString(CountdownText));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class BLASTER_API ABlasterPlayerController : public APlayerController
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void Tick(float DeltaSeconds) override;
|
virtual void Tick(float DeltaTime) override;
|
||||||
virtual void OnPossess(APawn* InPawn) override;
|
virtual void OnPossess(APawn* InPawn) override;
|
||||||
virtual void ReceivedPlayer() override; // Sync with server clock as soon as possible
|
virtual void ReceivedPlayer() override; // Sync with server clock as soon as possible
|
||||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||||
|
@ -63,7 +63,7 @@ protected:
|
||||||
void ServerCheckMatchState();
|
void ServerCheckMatchState();
|
||||||
|
|
||||||
UFUNCTION(Client, Reliable)
|
UFUNCTION(Client, Reliable)
|
||||||
void ClientJoinMidGame(FName StateOfMatch, float Warmup, float Match, float Cooldown, float StartingTime);
|
void ClientJoinMidgame(FName StateOfMatch, float Warmup, float Match, float Cooldown, float StartingTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
|
|
|
@ -7,21 +7,6 @@
|
||||||
#include "Blaster/PlayerController/BlasterPlayerController.h"
|
#include "Blaster/PlayerController/BlasterPlayerController.h"
|
||||||
#include "Net/UnrealNetwork.h"
|
#include "Net/UnrealNetwork.h"
|
||||||
|
|
||||||
void ABlasterPlayerState::IncreaseScore(float ScoreAmount)
|
|
||||||
{
|
|
||||||
SetScore(GetScore() + ScoreAmount);
|
|
||||||
|
|
||||||
Character = GetCharacter();
|
|
||||||
if (Character)
|
|
||||||
{
|
|
||||||
Controller = GetController();
|
|
||||||
if (Controller)
|
|
||||||
{
|
|
||||||
Controller->SetHUDScore(GetScore());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
void ABlasterPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||||
{
|
{
|
||||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||||
|
@ -29,14 +14,13 @@ void ABlasterPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>&
|
||||||
DOREPLIFETIME(ABlasterPlayerState, Defeats);
|
DOREPLIFETIME(ABlasterPlayerState, Defeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerState::OnRep_Score()
|
void ABlasterPlayerState::AddToScore(float ScoreAmount)
|
||||||
{
|
{
|
||||||
Super::OnRep_Score();
|
SetScore(GetScore() + ScoreAmount);
|
||||||
|
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;
|
||||||
Character = GetCharacter();
|
|
||||||
if (Character)
|
if (Character)
|
||||||
{
|
{
|
||||||
Controller = GetController();
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
if (Controller)
|
if (Controller)
|
||||||
{
|
{
|
||||||
Controller->SetHUDScore(GetScore());
|
Controller->SetHUDScore(GetScore());
|
||||||
|
@ -44,14 +28,28 @@ void ABlasterPlayerState::OnRep_Score()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerState::IncreaseDefeats(int32 DefeatsAmount)
|
void ABlasterPlayerState::OnRep_Score()
|
||||||
{
|
{
|
||||||
Defeats += DefeatsAmount;
|
Super::OnRep_Score();
|
||||||
|
|
||||||
Character = GetCharacter();
|
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;
|
||||||
if (Character)
|
if (Character)
|
||||||
{
|
{
|
||||||
Controller = GetController();
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
|
if (Controller)
|
||||||
|
{
|
||||||
|
Controller->SetHUDScore(GetScore());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerState::AddToDefeats(int32 DefeatsAmount)
|
||||||
|
{
|
||||||
|
Defeats += DefeatsAmount;
|
||||||
|
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;
|
||||||
|
if (Character)
|
||||||
|
{
|
||||||
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
if (Controller)
|
if (Controller)
|
||||||
{
|
{
|
||||||
Controller->SetHUDDefeats(Defeats);
|
Controller->SetHUDDefeats(Defeats);
|
||||||
|
@ -61,29 +59,13 @@ void ABlasterPlayerState::IncreaseDefeats(int32 DefeatsAmount)
|
||||||
|
|
||||||
void ABlasterPlayerState::OnRep_Defeats()
|
void ABlasterPlayerState::OnRep_Defeats()
|
||||||
{
|
{
|
||||||
Character = GetCharacter();
|
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;
|
||||||
if (Character)
|
if (Character)
|
||||||
{
|
{
|
||||||
Controller = GetController();
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
if (Controller)
|
if (Controller)
|
||||||
{
|
{
|
||||||
Controller->SetHUDDefeats(Defeats);
|
Controller->SetHUDDefeats(Defeats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ABlasterCharacter* ABlasterPlayerState::GetCharacter() const
|
|
||||||
{
|
|
||||||
return Character == nullptr ? Cast<ABlasterCharacter>(GetPawn()) : Character;
|
|
||||||
}
|
|
||||||
|
|
||||||
ABlasterPlayerController* ABlasterPlayerState::GetController() const
|
|
||||||
{
|
|
||||||
if (Character)
|
|
||||||
{
|
|
||||||
return Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -17,19 +17,18 @@ class BLASTER_API ABlasterPlayerState : public APlayerState
|
||||||
public:
|
public:
|
||||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||||
virtual void OnRep_Score() override;
|
virtual void OnRep_Score() override;
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
virtual void OnRep_Defeats();
|
virtual void OnRep_Defeats();
|
||||||
|
|
||||||
void IncreaseScore(float ScoreAmount);
|
void AddToScore(float ScoreAmount);
|
||||||
void IncreaseDefeats(int32 DefeatsAmount);
|
void AddToDefeats(int32 DefeatsAmount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
class ABlasterCharacter* Character;
|
class ABlasterCharacter* Character;
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
class ABlasterPlayerController* Controller;
|
class ABlasterPlayerController* Controller;
|
||||||
ABlasterCharacter* GetCharacter() const;
|
|
||||||
ABlasterPlayerController* GetController() const;
|
|
||||||
|
|
||||||
UPROPERTY(ReplicatedUsing = OnRep_Defeats)
|
UPROPERTY(ReplicatedUsing = OnRep_Defeats)
|
||||||
int32 Defeats;
|
int32 Defeats;
|
||||||
|
|
Loading…
Reference in New Issue