Some bug fixes and reorg
This commit is contained in:
parent
4fa586e648
commit
d2e581afe5
|
@ -49,11 +49,11 @@ ABlasterCharacter::ABlasterCharacter()
|
||||||
Combat = CreateDefaultSubobject<UCombatComponent>(TEXT("CombatComponent"));
|
Combat = CreateDefaultSubobject<UCombatComponent>(TEXT("CombatComponent"));
|
||||||
Combat->SetIsReplicated(true);
|
Combat->SetIsReplicated(true);
|
||||||
|
|
||||||
LagCompensation = CreateDefaultSubobject<ULagCompensationComponent>(TEXT("LagCompensation"));
|
|
||||||
|
|
||||||
Buff = CreateDefaultSubobject<UBuffComponent>(TEXT("BuffComponent"));
|
Buff = CreateDefaultSubobject<UBuffComponent>(TEXT("BuffComponent"));
|
||||||
Buff->SetIsReplicated(true);
|
Buff->SetIsReplicated(true);
|
||||||
|
|
||||||
|
LagCompensation = CreateDefaultSubobject<ULagCompensationComponent>(TEXT("LagCompensation"));
|
||||||
|
|
||||||
GetCharacterMovement()->NavAgentProps.bCanCrouch = true;
|
GetCharacterMovement()->NavAgentProps.bCanCrouch = true;
|
||||||
GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
|
GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
|
||||||
GetMesh()->SetCollisionObjectType(ECC_SkeletalMesh);
|
GetMesh()->SetCollisionObjectType(ECC_SkeletalMesh);
|
||||||
|
@ -112,15 +112,15 @@ ABlasterCharacter::ABlasterCharacter()
|
||||||
hand_r = CreateDefaultSubobject<UBoxComponent>(TEXT("hand_r"));
|
hand_r = CreateDefaultSubobject<UBoxComponent>(TEXT("hand_r"));
|
||||||
hand_r->SetupAttachment(GetMesh(), FName("hand_r"));
|
hand_r->SetupAttachment(GetMesh(), FName("hand_r"));
|
||||||
HitCollisionBoxes.Add(FName("hand_r"), hand_r);
|
HitCollisionBoxes.Add(FName("hand_r"), hand_r);
|
||||||
|
|
||||||
|
blanket = CreateDefaultSubobject<UBoxComponent>(TEXT("blanket"));
|
||||||
|
blanket->SetupAttachment(GetMesh(), FName("backpack"));
|
||||||
|
HitCollisionBoxes.Add(FName("blanket"), blanket);
|
||||||
|
|
||||||
backpack = CreateDefaultSubobject<UBoxComponent>(TEXT("backpack"));
|
backpack = CreateDefaultSubobject<UBoxComponent>(TEXT("backpack"));
|
||||||
backpack->SetupAttachment(GetMesh(), FName("backpack"));
|
backpack->SetupAttachment(GetMesh(), FName("backpack"));
|
||||||
HitCollisionBoxes.Add(FName("backpack"), backpack);
|
HitCollisionBoxes.Add(FName("backpack"), backpack);
|
||||||
|
|
||||||
blanket = CreateDefaultSubobject<UBoxComponent>(TEXT("blanket"));
|
|
||||||
blanket->SetupAttachment(GetMesh(), FName("backpack"));
|
|
||||||
HitCollisionBoxes.Add(FName("blanket"), blanket);
|
|
||||||
|
|
||||||
thigh_l = CreateDefaultSubobject<UBoxComponent>(TEXT("thigh_l"));
|
thigh_l = CreateDefaultSubobject<UBoxComponent>(TEXT("thigh_l"));
|
||||||
thigh_l->SetupAttachment(GetMesh(), FName("thigh_l"));
|
thigh_l->SetupAttachment(GetMesh(), FName("thigh_l"));
|
||||||
HitCollisionBoxes.Add(FName("thigh_l"), thigh_l);
|
HitCollisionBoxes.Add(FName("thigh_l"), thigh_l);
|
||||||
|
@ -200,9 +200,9 @@ void ABlasterCharacter::MulticastEliminated_Implementation(bool bPlayerLeftGame)
|
||||||
StartDissolve();
|
StartDissolve();
|
||||||
|
|
||||||
// Disable character movement
|
// Disable character movement
|
||||||
|
bDisableGameplay = true;
|
||||||
GetCharacterMovement()->DisableMovement();
|
GetCharacterMovement()->DisableMovement();
|
||||||
GetCharacterMovement()->StopMovementImmediately();
|
GetCharacterMovement()->StopMovementImmediately();
|
||||||
bDisableGameplay = true;
|
|
||||||
if (Combat)
|
if (Combat)
|
||||||
{
|
{
|
||||||
Combat->FireButtonPressed(false);
|
Combat->FireButtonPressed(false);
|
||||||
|
@ -280,10 +280,9 @@ void ABlasterCharacter::Destroyed()
|
||||||
|
|
||||||
ABlasterGameMode* BlasterGameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
|
ABlasterGameMode* BlasterGameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
|
||||||
bool bMatchNotInProgress = BlasterGameMode && BlasterGameMode->GetMatchState() != MatchState::InProgress;
|
bool bMatchNotInProgress = BlasterGameMode && BlasterGameMode->GetMatchState() != MatchState::InProgress;
|
||||||
|
if (Combat && Combat->EquippedWeapon && bMatchNotInProgress)
|
||||||
if (Combat && Combat->PrimaryWeapon && bMatchNotInProgress)
|
|
||||||
{
|
{
|
||||||
Combat->PrimaryWeapon->Destroy();
|
Combat->EquippedWeapon->Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +301,6 @@ void ABlasterCharacter::MulticastGainedTheLead_Implementation()
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CrownComponent)
|
if (CrownComponent)
|
||||||
{
|
{
|
||||||
CrownComponent->Activate();
|
CrownComponent->Activate();
|
||||||
|
@ -320,7 +318,6 @@ void ABlasterCharacter::MulticastLostTheLead_Implementation()
|
||||||
void ABlasterCharacter::BeginPlay()
|
void ABlasterCharacter::BeginPlay()
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
|
|
||||||
SpawnDefaultWeapon();
|
SpawnDefaultWeapon();
|
||||||
UpdateHUDAmmo();
|
UpdateHUDAmmo();
|
||||||
UpdateHUDHealth();
|
UpdateHUDHealth();
|
||||||
|
@ -413,7 +410,7 @@ void ABlasterCharacter::PostInitializeComponents()
|
||||||
|
|
||||||
void ABlasterCharacter::PlayFireMontage(bool bAiming)
|
void ABlasterCharacter::PlayFireMontage(bool bAiming)
|
||||||
{
|
{
|
||||||
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
||||||
if (AnimInstance && FireWeaponMontage)
|
if (AnimInstance && FireWeaponMontage)
|
||||||
|
@ -427,7 +424,7 @@ void ABlasterCharacter::PlayFireMontage(bool bAiming)
|
||||||
|
|
||||||
void ABlasterCharacter::PlayReloadMontage()
|
void ABlasterCharacter::PlayReloadMontage()
|
||||||
{
|
{
|
||||||
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
||||||
if (AnimInstance && ReloadMontage)
|
if (AnimInstance && ReloadMontage)
|
||||||
|
@ -435,7 +432,7 @@ void ABlasterCharacter::PlayReloadMontage()
|
||||||
AnimInstance->Montage_Play(ReloadMontage);
|
AnimInstance->Montage_Play(ReloadMontage);
|
||||||
FName SectionName;
|
FName SectionName;
|
||||||
|
|
||||||
switch (Combat->PrimaryWeapon->GetWeaponType())
|
switch (Combat->EquippedWeapon->GetWeaponType())
|
||||||
{
|
{
|
||||||
case EWeaponType::EWT_AssaultRifle:
|
case EWeaponType::EWT_AssaultRifle:
|
||||||
SectionName = FName("Rifle");
|
SectionName = FName("Rifle");
|
||||||
|
@ -496,7 +493,7 @@ void ABlasterCharacter::PlaySwapMontage()
|
||||||
|
|
||||||
void ABlasterCharacter::PlayHitReactMontage()
|
void ABlasterCharacter::PlayHitReactMontage()
|
||||||
{
|
{
|
||||||
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
|
||||||
if (AnimInstance && HitReactMontage)
|
if (AnimInstance && HitReactMontage)
|
||||||
|
@ -507,6 +504,14 @@ void ABlasterCharacter::PlayHitReactMontage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABlasterCharacter::GrenadeButtonPressed()
|
||||||
|
{
|
||||||
|
if (Combat)
|
||||||
|
{
|
||||||
|
Combat->ThrowGrenade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatorController, AActor* DamageCauser)
|
void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatorController, AActor* DamageCauser)
|
||||||
{
|
{
|
||||||
if (bEliminated) return;
|
if (bEliminated) return;
|
||||||
|
@ -521,8 +526,8 @@ void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DamageToHealth = FMath::Clamp(DamageToHealth - (Damage - Shield), 0.f, Damage);
|
|
||||||
Shield = 0.f;
|
Shield = 0.f;
|
||||||
|
DamageToHealth = FMath::Clamp(DamageToHealth - (Damage - Shield), 0.f, Damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,14 +659,6 @@ void ABlasterCharacter::AimButtonReleased()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::GrenadeButtonPressed()
|
|
||||||
{
|
|
||||||
if (Combat)
|
|
||||||
{
|
|
||||||
Combat->ThrowGrenade();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float ABlasterCharacter::CalculateSpeed()
|
float ABlasterCharacter::CalculateSpeed()
|
||||||
{
|
{
|
||||||
FVector Velocity = GetVelocity();
|
FVector Velocity = GetVelocity();
|
||||||
|
@ -671,7 +668,7 @@ float ABlasterCharacter::CalculateSpeed()
|
||||||
|
|
||||||
void ABlasterCharacter::AimOffset(float DeltaTime)
|
void ABlasterCharacter::AimOffset(float DeltaTime)
|
||||||
{
|
{
|
||||||
if (Combat && Combat->PrimaryWeapon == nullptr) return;
|
if (Combat && Combat->EquippedWeapon == nullptr) return;
|
||||||
float Speed = CalculateSpeed();
|
float Speed = CalculateSpeed();
|
||||||
bool bIsInAir = GetCharacterMovement()->IsFalling();
|
bool bIsInAir = GetCharacterMovement()->IsFalling();
|
||||||
|
|
||||||
|
@ -714,7 +711,7 @@ void ABlasterCharacter::CalculateAO_Pitch()
|
||||||
|
|
||||||
void ABlasterCharacter::SimProxiesTurn()
|
void ABlasterCharacter::SimProxiesTurn()
|
||||||
{
|
{
|
||||||
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
|
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
|
||||||
bRotateRootBone = false;
|
bRotateRootBone = false;
|
||||||
float Speed = CalculateSpeed();
|
float Speed = CalculateSpeed();
|
||||||
if (Speed > 0.f)
|
if (Speed > 0.f)
|
||||||
|
@ -806,9 +803,9 @@ void ABlasterCharacter::HideCameraIfCharacterClose()
|
||||||
if ((FollowCamera->GetComponentLocation() - GetActorLocation()).Size() < CameraThreshold)
|
if ((FollowCamera->GetComponentLocation() - GetActorLocation()).Size() < CameraThreshold)
|
||||||
{
|
{
|
||||||
GetMesh()->SetVisibility(false);
|
GetMesh()->SetVisibility(false);
|
||||||
if (Combat && Combat->PrimaryWeapon && Combat->PrimaryWeapon->GetWeaponMesh())
|
if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh())
|
||||||
{
|
{
|
||||||
Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = true;
|
Combat->EquippedWeapon->GetWeaponMesh()->bOwnerNoSee = true;
|
||||||
}
|
}
|
||||||
if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh())
|
if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh())
|
||||||
{
|
{
|
||||||
|
@ -818,9 +815,9 @@ void ABlasterCharacter::HideCameraIfCharacterClose()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GetMesh()->SetVisibility(true);
|
GetMesh()->SetVisibility(true);
|
||||||
if (Combat && Combat->PrimaryWeapon && Combat->PrimaryWeapon->GetWeaponMesh())
|
if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh())
|
||||||
{
|
{
|
||||||
Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = false;
|
Combat->EquippedWeapon->GetWeaponMesh()->bOwnerNoSee = false;
|
||||||
}
|
}
|
||||||
if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh())
|
if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh())
|
||||||
{
|
{
|
||||||
|
@ -868,10 +865,10 @@ void ABlasterCharacter::UpdateHUDShield()
|
||||||
void ABlasterCharacter::UpdateHUDAmmo()
|
void ABlasterCharacter::UpdateHUDAmmo()
|
||||||
{
|
{
|
||||||
BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;
|
BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;
|
||||||
if (BlasterPlayerController && Combat && Combat->PrimaryWeapon)
|
if (BlasterPlayerController && Combat && Combat->EquippedWeapon)
|
||||||
{
|
{
|
||||||
BlasterPlayerController->SetHUDCarriedAmmo(Combat->CarriedAmmo);
|
BlasterPlayerController->SetHUDCarriedAmmo(Combat->CarriedAmmo);
|
||||||
BlasterPlayerController->SetHUDWeaponAmmo(Combat->PrimaryWeapon->GetAmmo());
|
BlasterPlayerController->SetHUDWeaponAmmo(Combat->EquippedWeapon->GetAmmo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,7 +905,6 @@ void ABlasterCharacter::PollInit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterCharacter::UpdateDissolveMaterial(float DissolveValue)
|
void ABlasterCharacter::UpdateDissolveMaterial(float DissolveValue)
|
||||||
|
@ -959,7 +955,7 @@ void ABlasterCharacter::OnRep_OverlappingWeapon(AWeapon* LastWeapon)
|
||||||
|
|
||||||
bool ABlasterCharacter::IsWeaponEquipped()
|
bool ABlasterCharacter::IsWeaponEquipped()
|
||||||
{
|
{
|
||||||
return Combat && Combat->PrimaryWeapon;
|
return Combat && Combat->EquippedWeapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ABlasterCharacter::IsAiming()
|
bool ABlasterCharacter::IsAiming()
|
||||||
|
@ -970,7 +966,7 @@ bool ABlasterCharacter::IsAiming()
|
||||||
AWeapon* ABlasterCharacter::GetPrimaryWeapon()
|
AWeapon* ABlasterCharacter::GetPrimaryWeapon()
|
||||||
{
|
{
|
||||||
if (Combat == nullptr) return nullptr;
|
if (Combat == nullptr) return nullptr;
|
||||||
return Combat->PrimaryWeapon;
|
return Combat->EquippedWeapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
FVector ABlasterCharacter::GetHitTarget() const
|
FVector ABlasterCharacter::GetHitTarget() const
|
||||||
|
|
|
@ -25,7 +25,7 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out
|
||||||
{
|
{
|
||||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||||
|
|
||||||
DOREPLIFETIME(UCombatComponent, PrimaryWeapon);
|
DOREPLIFETIME(UCombatComponent, EquippedWeapon);
|
||||||
DOREPLIFETIME(UCombatComponent, SecondaryWeapon);
|
DOREPLIFETIME(UCombatComponent, SecondaryWeapon);
|
||||||
DOREPLIFETIME(UCombatComponent, bAiming);
|
DOREPLIFETIME(UCombatComponent, bAiming);
|
||||||
DOREPLIFETIME_CONDITION(UCombatComponent, CarriedAmmo, COND_OwnerOnly);
|
DOREPLIFETIME_CONDITION(UCombatComponent, CarriedAmmo, COND_OwnerOnly);
|
||||||
|
@ -33,6 +33,14 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out
|
||||||
DOREPLIFETIME(UCombatComponent, Grenades);
|
DOREPLIFETIME(UCombatComponent, Grenades);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::ShotgunShellReload()
|
||||||
|
{
|
||||||
|
if (Character && Character->HasAuthority())
|
||||||
|
{
|
||||||
|
UpdateShotgunAmmoValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount)
|
void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount)
|
||||||
{
|
{
|
||||||
if (CarriedAmmoMap.Contains(WeaponType))
|
if (CarriedAmmoMap.Contains(WeaponType))
|
||||||
|
@ -40,7 +48,7 @@ void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount)
|
||||||
CarriedAmmoMap[WeaponType] = FMath::Clamp(CarriedAmmoMap[WeaponType] + AmmoAmount, 0, MaxCarriedAmmo);
|
CarriedAmmoMap[WeaponType] = FMath::Clamp(CarriedAmmoMap[WeaponType] + AmmoAmount, 0, MaxCarriedAmmo);
|
||||||
UpdateCarriedAmmo();
|
UpdateCarriedAmmo();
|
||||||
}
|
}
|
||||||
if (PrimaryWeapon && PrimaryWeapon->IsEmpty() && PrimaryWeapon->GetWeaponType() == WeaponType)
|
if (EquippedWeapon && EquippedWeapon->IsEmpty() && EquippedWeapon->GetWeaponType() == WeaponType)
|
||||||
{
|
{
|
||||||
Reload();
|
Reload();
|
||||||
}
|
}
|
||||||
|
@ -84,29 +92,22 @@ void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActo
|
||||||
void UCombatComponent::FireButtonPressed(bool bPressed)
|
void UCombatComponent::FireButtonPressed(bool bPressed)
|
||||||
{
|
{
|
||||||
bFireButtonPressed = bPressed;
|
bFireButtonPressed = bPressed;
|
||||||
if (bFireButtonPressed && PrimaryWeapon)
|
if (bFireButtonPressed)
|
||||||
{
|
{
|
||||||
Fire();
|
Fire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::ShotgunShellReload()
|
|
||||||
{
|
|
||||||
if (Character && Character->HasAuthority())
|
|
||||||
{
|
|
||||||
UpdateShotgunAmmoValues();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::Fire()
|
void UCombatComponent::Fire()
|
||||||
{
|
{
|
||||||
if (CanFire())
|
if (CanFire())
|
||||||
{
|
{
|
||||||
bCanFire = false;
|
bCanFire = false;
|
||||||
if (PrimaryWeapon)
|
if (EquippedWeapon)
|
||||||
{
|
{
|
||||||
CrosshairShootingFactor = .75f;
|
CrosshairShootingFactor = .75f;
|
||||||
switch (PrimaryWeapon->FireType)
|
|
||||||
|
switch (EquippedWeapon->FireType)
|
||||||
{
|
{
|
||||||
case EFireType::EFT_HitScan:
|
case EFireType::EFT_HitScan:
|
||||||
FireHitScanWeapon();
|
FireHitScanWeapon();
|
||||||
|
@ -125,52 +126,52 @@ void UCombatComponent::Fire()
|
||||||
|
|
||||||
void UCombatComponent::FireProjectileWeapon()
|
void UCombatComponent::FireProjectileWeapon()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon && Character)
|
if (EquippedWeapon && Character)
|
||||||
{
|
{
|
||||||
HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
|
HitTarget = EquippedWeapon->bUseScatter ? EquippedWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
|
||||||
if (!Character->HasAuthority()) LocalFire(HitTarget);
|
if (!Character->HasAuthority()) LocalFire(HitTarget);
|
||||||
ServerFire(HitTarget, PrimaryWeapon->FireDelay);
|
ServerFire(HitTarget, EquippedWeapon->FireDelay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::FireHitScanWeapon()
|
void UCombatComponent::FireHitScanWeapon()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon && Character)
|
if (EquippedWeapon && Character)
|
||||||
{
|
{
|
||||||
HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
|
HitTarget = EquippedWeapon->bUseScatter ? EquippedWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
|
||||||
if (!Character->HasAuthority()) LocalFire(HitTarget);
|
if (!Character->HasAuthority()) LocalFire(HitTarget);
|
||||||
ServerFire(HitTarget, PrimaryWeapon->FireDelay);
|
ServerFire(HitTarget, EquippedWeapon->FireDelay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::FireShotgun()
|
void UCombatComponent::FireShotgun()
|
||||||
{
|
{
|
||||||
AShotgun* Shotgun = Cast<AShotgun>(PrimaryWeapon);
|
AShotgun* Shotgun = Cast<AShotgun>(EquippedWeapon);
|
||||||
if (Shotgun && Character)
|
if (Shotgun && Character)
|
||||||
{
|
{
|
||||||
TArray<FVector_NetQuantize> HitTargets;
|
TArray<FVector_NetQuantize> HitTargets;
|
||||||
Shotgun->ShotgunTraceEndWithScatter(HitTarget, HitTargets);
|
Shotgun->ShotgunTraceEndWithScatter(HitTarget, HitTargets);
|
||||||
if (!Character->HasAuthority()) ShotgunLocalFire(HitTargets);
|
if (!Character->HasAuthority()) ShotgunLocalFire(HitTargets);
|
||||||
ServerShotgunFire(HitTargets, PrimaryWeapon->FireDelay);
|
ServerShotgunFire(HitTargets, EquippedWeapon->FireDelay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::StartFireTimer()
|
void UCombatComponent::StartFireTimer()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr || Character == nullptr) return;
|
if (EquippedWeapon == nullptr || Character == nullptr) return;
|
||||||
Character->GetWorldTimerManager().SetTimer(
|
Character->GetWorldTimerManager().SetTimer(
|
||||||
FireTimer,
|
FireTimer,
|
||||||
this,
|
this,
|
||||||
&UCombatComponent::FireTimerFinished,
|
&UCombatComponent::FireTimerFinished,
|
||||||
PrimaryWeapon->FireDelay
|
EquippedWeapon->FireDelay
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::FireTimerFinished()
|
void UCombatComponent::FireTimerFinished()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return;
|
if (EquippedWeapon == nullptr) return;
|
||||||
bCanFire = true;
|
bCanFire = true;
|
||||||
if (bFireButtonPressed && PrimaryWeapon->bAutomatic)
|
if (bFireButtonPressed && EquippedWeapon->bAutomatic)
|
||||||
{
|
{
|
||||||
Fire();
|
Fire();
|
||||||
}
|
}
|
||||||
|
@ -184,8 +185,8 @@ void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& Trac
|
||||||
|
|
||||||
bool UCombatComponent::ServerFire_Validate(const FVector_NetQuantize& TraceHitTarget, float FireDelay)
|
bool UCombatComponent::ServerFire_Validate(const FVector_NetQuantize& TraceHitTarget, float FireDelay)
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return true;
|
if (EquippedWeapon == nullptr) return true;
|
||||||
return FMath::IsNearlyEqual(PrimaryWeapon->FireDelay, FireDelay, 0.001f);
|
return FMath::IsNearlyEqual(EquippedWeapon->FireDelay, FireDelay, 0.001f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
|
void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
|
||||||
|
@ -201,8 +202,8 @@ void UCombatComponent::ServerShotgunFire_Implementation(const TArray<FVector_Net
|
||||||
|
|
||||||
bool UCombatComponent::ServerShotgunFire_Validate(const TArray<FVector_NetQuantize>& TraceHitTargets, float FireDelay)
|
bool UCombatComponent::ServerShotgunFire_Validate(const TArray<FVector_NetQuantize>& TraceHitTargets, float FireDelay)
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return true;
|
if (EquippedWeapon == nullptr) return true;
|
||||||
return FMath::IsNearlyEqual(PrimaryWeapon->FireDelay, FireDelay, 0.001f);
|
return FMath::IsNearlyEqual(EquippedWeapon->FireDelay, FireDelay, 0.001f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::MulticastShotgunFire_Implementation(const TArray<FVector_NetQuantize>& TraceHitTargets)
|
void UCombatComponent::MulticastShotgunFire_Implementation(const TArray<FVector_NetQuantize>& TraceHitTargets)
|
||||||
|
@ -213,20 +214,21 @@ void UCombatComponent::MulticastShotgunFire_Implementation(const TArray<FVector_
|
||||||
|
|
||||||
void UCombatComponent::LocalFire(const FVector_NetQuantize& TraceHitTarget)
|
void UCombatComponent::LocalFire(const FVector_NetQuantize& TraceHitTarget)
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return;
|
if (EquippedWeapon == nullptr) return;
|
||||||
if (Character && CombatState == ECombatState::ECS_Unoccupied)
|
if (Character && CombatState == ECombatState::ECS_Unoccupied)
|
||||||
{
|
{
|
||||||
Character->PlayFireMontage(bAiming);
|
Character->PlayFireMontage(bAiming);
|
||||||
PrimaryWeapon->Fire(TraceHitTarget);
|
EquippedWeapon->Fire(TraceHitTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets)
|
void UCombatComponent::ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets)
|
||||||
{
|
{
|
||||||
AShotgun* Shotgun = Cast<AShotgun>(PrimaryWeapon);
|
AShotgun* Shotgun = Cast<AShotgun>(EquippedWeapon);
|
||||||
if (Shotgun == nullptr || Character == nullptr) return;
|
if (Shotgun == nullptr || Character == nullptr) return;
|
||||||
if (CombatState == ECombatState::ECS_Reloading || CombatState == ECombatState::ECS_Unoccupied)
|
if (CombatState == ECombatState::ECS_Reloading || CombatState == ECombatState::ECS_Unoccupied)
|
||||||
{
|
{
|
||||||
|
bLocallyReloading = false;
|
||||||
Character->PlayFireMontage(bAiming);
|
Character->PlayFireMontage(bAiming);
|
||||||
Shotgun->FireShotgun(TraceHitTargets);
|
Shotgun->FireShotgun(TraceHitTargets);
|
||||||
CombatState = ECombatState::ECS_Unoccupied;
|
CombatState = ECombatState::ECS_Unoccupied;
|
||||||
|
@ -238,7 +240,7 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip)
|
||||||
if (Character == nullptr || WeaponToEquip == nullptr) return;
|
if (Character == nullptr || WeaponToEquip == nullptr) return;
|
||||||
if (CombatState != ECombatState::ECS_Unoccupied) return;
|
if (CombatState != ECombatState::ECS_Unoccupied) return;
|
||||||
|
|
||||||
if (PrimaryWeapon != nullptr && SecondaryWeapon == nullptr)
|
if (EquippedWeapon != nullptr && SecondaryWeapon == nullptr)
|
||||||
{
|
{
|
||||||
EquipSecondaryWeapon(WeaponToEquip);
|
EquipSecondaryWeapon(WeaponToEquip);
|
||||||
}
|
}
|
||||||
|
@ -262,23 +264,17 @@ void UCombatComponent::SwapWeapons()
|
||||||
if (SecondaryWeapon) SecondaryWeapon->EnableCustomDepth(false);
|
if (SecondaryWeapon) SecondaryWeapon->EnableCustomDepth(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UCombatComponent::ShouldSwapWeapons()
|
|
||||||
{
|
|
||||||
return PrimaryWeapon != nullptr && SecondaryWeapon != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::EquipPrimaryWeapon(AWeapon* WeaponToEquip)
|
void UCombatComponent::EquipPrimaryWeapon(AWeapon* WeaponToEquip)
|
||||||
{
|
{
|
||||||
if (WeaponToEquip == nullptr) return;
|
if (WeaponToEquip == nullptr) return;
|
||||||
|
DropEquippedWeapon();
|
||||||
DropPrimaryWeapon();
|
EquippedWeapon = WeaponToEquip;
|
||||||
PrimaryWeapon = WeaponToEquip;
|
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
||||||
PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
AttachActorToRightHand(EquippedWeapon);
|
||||||
AttachActorToRightHand(PrimaryWeapon);
|
EquippedWeapon->SetOwner(Character);
|
||||||
PrimaryWeapon->SetOwner(Character);
|
EquippedWeapon->SetHUDAmmo();
|
||||||
PrimaryWeapon->SetHUDAmmo();
|
|
||||||
UpdateCarriedAmmo();
|
UpdateCarriedAmmo();
|
||||||
PlayEquipWeaponSound(PrimaryWeapon);
|
PlayEquipWeaponSound(WeaponToEquip);
|
||||||
ReloadEmptyWeapon();
|
ReloadEmptyWeapon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,44 +284,29 @@ void UCombatComponent::EquipSecondaryWeapon(AWeapon* WeaponToEquip)
|
||||||
SecondaryWeapon = WeaponToEquip;
|
SecondaryWeapon = WeaponToEquip;
|
||||||
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
|
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
|
||||||
AttachActorToBackpack(WeaponToEquip);
|
AttachActorToBackpack(WeaponToEquip);
|
||||||
PlayEquipWeaponSound(SecondaryWeapon);
|
PlayEquipWeaponSound(WeaponToEquip);
|
||||||
SecondaryWeapon->SetOwner(Character);
|
SecondaryWeapon->SetOwner(Character);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::OnRep_PrimaryWeapon()
|
void UCombatComponent::OnRep_Aiming()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon && Character)
|
if (Character && Character->IsLocallyControlled())
|
||||||
{
|
{
|
||||||
PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
bAiming = bAimButtonPressed;
|
||||||
AttachActorToRightHand(PrimaryWeapon);
|
|
||||||
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
|
|
||||||
Character->bUseControllerRotationYaw = true;
|
|
||||||
PlayEquipWeaponSound(PrimaryWeapon);
|
|
||||||
PrimaryWeapon->SetHUDAmmo();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::OnRep_SecondaryWeapon()
|
void UCombatComponent::DropEquippedWeapon()
|
||||||
{
|
{
|
||||||
if (SecondaryWeapon && Character)
|
if (EquippedWeapon)
|
||||||
{
|
{
|
||||||
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
|
EquippedWeapon->Dropped();
|
||||||
AttachActorToBackpack(SecondaryWeapon);
|
|
||||||
PlayEquipWeaponSound(SecondaryWeapon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::DropPrimaryWeapon()
|
|
||||||
{
|
|
||||||
if (PrimaryWeapon)
|
|
||||||
{
|
|
||||||
PrimaryWeapon->Dropped();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::AttachActorToRightHand(AActor* ActorToAttach)
|
void UCombatComponent::AttachActorToRightHand(AActor* ActorToAttach)
|
||||||
{
|
{
|
||||||
if (Character == nullptr || Character->GetMesh() == nullptr|| ActorToAttach == nullptr) return;
|
if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr) return;
|
||||||
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));
|
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));
|
||||||
if (HandSocket)
|
if (HandSocket)
|
||||||
{
|
{
|
||||||
|
@ -335,8 +316,8 @@ void UCombatComponent::AttachActorToRightHand(AActor* ActorToAttach)
|
||||||
|
|
||||||
void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach)
|
void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach)
|
||||||
{
|
{
|
||||||
if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || PrimaryWeapon == nullptr) return;
|
if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || EquippedWeapon == nullptr) return;
|
||||||
bool bUsePistolSocket = PrimaryWeapon->IsPistol() || PrimaryWeapon->IsSMG();
|
bool bUsePistolSocket = EquippedWeapon->IsPistol() || EquippedWeapon->IsSMG();
|
||||||
FName SocketName = bUsePistolSocket ? FName("LeftHandPistolSocket") : FName("LeftHandSocket");
|
FName SocketName = bUsePistolSocket ? FName("LeftHandPistolSocket") : FName("LeftHandSocket");
|
||||||
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(SocketName);
|
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(SocketName);
|
||||||
if (HandSocket)
|
if (HandSocket)
|
||||||
|
@ -347,7 +328,7 @@ void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach)
|
||||||
|
|
||||||
void UCombatComponent::AttachActorToBackpack(AActor* ActorToAttach)
|
void UCombatComponent::AttachActorToBackpack(AActor* ActorToAttach)
|
||||||
{
|
{
|
||||||
if (Character == nullptr || Character->GetMesh() == nullptr|| ActorToAttach == nullptr) return;
|
if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr) return;
|
||||||
const USkeletalMeshSocket* BackpackSocket = Character->GetMesh()->GetSocketByName(FName("BackpackSocket"));
|
const USkeletalMeshSocket* BackpackSocket = Character->GetMesh()->GetSocketByName(FName("BackpackSocket"));
|
||||||
if (BackpackSocket)
|
if (BackpackSocket)
|
||||||
{
|
{
|
||||||
|
@ -357,10 +338,10 @@ void UCombatComponent::AttachActorToBackpack(AActor* ActorToAttach)
|
||||||
|
|
||||||
void UCombatComponent::UpdateCarriedAmmo()
|
void UCombatComponent::UpdateCarriedAmmo()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return;
|
if (EquippedWeapon == nullptr) return;
|
||||||
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
|
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
||||||
{
|
{
|
||||||
CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
|
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
|
@ -370,13 +351,13 @@ void UCombatComponent::UpdateCarriedAmmo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::PlayEquipWeaponSound(const AWeapon* Weapon)
|
void UCombatComponent::PlayEquipWeaponSound(const AWeapon* WeaponToEquip)
|
||||||
{
|
{
|
||||||
if (Character && Weapon && Weapon->EquipSound)
|
if (Character && WeaponToEquip && WeaponToEquip->EquipSound)
|
||||||
{
|
{
|
||||||
UGameplayStatics::PlaySoundAtLocation(
|
UGameplayStatics::PlaySoundAtLocation(
|
||||||
this,
|
this,
|
||||||
Weapon->EquipSound,
|
WeaponToEquip->EquipSound,
|
||||||
Character->GetActorLocation()
|
Character->GetActorLocation()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +365,7 @@ void UCombatComponent::PlayEquipWeaponSound(const AWeapon* Weapon)
|
||||||
|
|
||||||
void UCombatComponent::ReloadEmptyWeapon()
|
void UCombatComponent::ReloadEmptyWeapon()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon && PrimaryWeapon->IsEmpty())
|
if (EquippedWeapon && EquippedWeapon->IsEmpty())
|
||||||
{
|
{
|
||||||
Reload();
|
Reload();
|
||||||
}
|
}
|
||||||
|
@ -392,7 +373,7 @@ void UCombatComponent::ReloadEmptyWeapon()
|
||||||
|
|
||||||
void UCombatComponent::Reload()
|
void UCombatComponent::Reload()
|
||||||
{
|
{
|
||||||
if (CarriedAmmo > 0 && CombatState == ECombatState::ECS_Unoccupied && PrimaryWeapon && !PrimaryWeapon->IsFull() && !bLocallyReloading)
|
if (CarriedAmmo > 0 && CombatState == ECombatState::ECS_Unoccupied && EquippedWeapon && !EquippedWeapon->IsFull() && !bLocallyReloading)
|
||||||
{
|
{
|
||||||
ServerReload();
|
ServerReload();
|
||||||
HandleReload();
|
HandleReload();
|
||||||
|
@ -402,10 +383,10 @@ void UCombatComponent::Reload()
|
||||||
|
|
||||||
void UCombatComponent::ServerReload_Implementation()
|
void UCombatComponent::ServerReload_Implementation()
|
||||||
{
|
{
|
||||||
if (Character == nullptr || PrimaryWeapon == nullptr) return;
|
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
// return if weapon mag is at max capacity
|
// return if weapon mag is at max capacity
|
||||||
if (PrimaryWeapon->GetAmmo() == PrimaryWeapon->GetMagCapacity()) return;
|
if (EquippedWeapon->GetAmmo() == EquippedWeapon->GetMagCapacity()) return;
|
||||||
|
|
||||||
CombatState = ECombatState::ECS_Reloading;
|
CombatState = ECombatState::ECS_Reloading;
|
||||||
if (!Character->IsLocallyControlled()) HandleReload();
|
if (!Character->IsLocallyControlled()) HandleReload();
|
||||||
|
@ -438,15 +419,17 @@ void UCombatComponent::FinishedSwap()
|
||||||
|
|
||||||
void UCombatComponent::FinishedSwapAttachWeapons()
|
void UCombatComponent::FinishedSwapAttachWeapons()
|
||||||
{
|
{
|
||||||
AWeapon* TempWeapon = PrimaryWeapon;
|
PlayEquipWeaponSound(SecondaryWeapon);
|
||||||
PrimaryWeapon = SecondaryWeapon;
|
|
||||||
|
if (Character == nullptr || !Character->HasAuthority()) return;
|
||||||
|
AWeapon* TempWeapon = EquippedWeapon;
|
||||||
|
EquippedWeapon = SecondaryWeapon;
|
||||||
SecondaryWeapon = TempWeapon;
|
SecondaryWeapon = TempWeapon;
|
||||||
|
|
||||||
PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
||||||
AttachActorToRightHand(PrimaryWeapon);
|
AttachActorToRightHand(EquippedWeapon);
|
||||||
PrimaryWeapon->SetHUDAmmo();
|
EquippedWeapon->SetHUDAmmo();
|
||||||
UpdateCarriedAmmo();
|
UpdateCarriedAmmo();
|
||||||
PlayEquipWeaponSound(PrimaryWeapon);
|
|
||||||
|
|
||||||
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
|
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
|
||||||
AttachActorToBackpack(SecondaryWeapon);
|
AttachActorToBackpack(SecondaryWeapon);
|
||||||
|
@ -454,49 +437,54 @@ void UCombatComponent::FinishedSwapAttachWeapons()
|
||||||
|
|
||||||
void UCombatComponent::DropWeapons()
|
void UCombatComponent::DropWeapons()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon) PrimaryWeapon->Dropped();
|
if (EquippedWeapon) EquippedWeapon->Dropped();
|
||||||
if (SecondaryWeapon) SecondaryWeapon->Dropped();
|
if (SecondaryWeapon) SecondaryWeapon->Dropped();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::UpdateAmmoValues()
|
void UCombatComponent::UpdateAmmoValues()
|
||||||
{
|
{
|
||||||
if (Character == nullptr || PrimaryWeapon == nullptr) return;
|
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
||||||
int32 ReloadAmount = AmountToReload();
|
int32 ReloadAmount = AmountToReload();
|
||||||
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
|
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
||||||
{
|
{
|
||||||
CarriedAmmoMap[PrimaryWeapon->GetWeaponType()] -= ReloadAmount;
|
CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= ReloadAmount;
|
||||||
CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
|
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
||||||
}
|
}
|
||||||
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
if (Controller)
|
if (Controller)
|
||||||
{
|
{
|
||||||
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
||||||
}
|
}
|
||||||
PrimaryWeapon->AddAmmo(ReloadAmount);
|
EquippedWeapon->AddAmmo(ReloadAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::UpdateShotgunAmmoValues()
|
void UCombatComponent::UpdateShotgunAmmoValues()
|
||||||
{
|
{
|
||||||
if (Character == nullptr || PrimaryWeapon == nullptr) return;
|
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
|
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
||||||
{
|
{
|
||||||
CarriedAmmoMap[PrimaryWeapon->GetWeaponType()] -= 1;
|
CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= 1;
|
||||||
CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
|
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
||||||
}
|
}
|
||||||
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
if (Controller)
|
if (Controller)
|
||||||
{
|
{
|
||||||
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
||||||
}
|
}
|
||||||
PrimaryWeapon->AddAmmo(1);
|
EquippedWeapon->AddAmmo(1);
|
||||||
bCanFire = true;
|
bCanFire = true;
|
||||||
if (PrimaryWeapon->IsFull() || CarriedAmmo == 0)
|
if (EquippedWeapon->IsFull() || CarriedAmmo == 0)
|
||||||
{
|
{
|
||||||
JumpToShotgunEnd();
|
JumpToShotgunEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::OnRep_Grenades()
|
||||||
|
{
|
||||||
|
UpdateHUDGrenades();
|
||||||
|
}
|
||||||
|
|
||||||
void UCombatComponent::JumpToShotgunEnd()
|
void UCombatComponent::JumpToShotgunEnd()
|
||||||
{
|
{
|
||||||
// Jump to ShotgunEnd section
|
// Jump to ShotgunEnd section
|
||||||
|
@ -510,7 +498,7 @@ void UCombatComponent::JumpToShotgunEnd()
|
||||||
void UCombatComponent::ThrowGrenadeFinished()
|
void UCombatComponent::ThrowGrenadeFinished()
|
||||||
{
|
{
|
||||||
CombatState = ECombatState::ECS_Unoccupied;
|
CombatState = ECombatState::ECS_Unoccupied;
|
||||||
AttachActorToRightHand(PrimaryWeapon);
|
AttachActorToRightHand(EquippedWeapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::LaunchGrenade()
|
void UCombatComponent::LaunchGrenade()
|
||||||
|
@ -531,7 +519,6 @@ void UCombatComponent::ServerLaunchGrenade_Implementation(const FVector_NetQuant
|
||||||
FActorSpawnParameters SpawnParams;
|
FActorSpawnParameters SpawnParams;
|
||||||
SpawnParams.Owner = Character;
|
SpawnParams.Owner = Character;
|
||||||
SpawnParams.Instigator = Character;
|
SpawnParams.Instigator = Character;
|
||||||
|
|
||||||
UWorld* World = GetWorld();
|
UWorld* World = GetWorld();
|
||||||
if (World)
|
if (World)
|
||||||
{
|
{
|
||||||
|
@ -562,7 +549,7 @@ void UCombatComponent::OnRep_CombatState()
|
||||||
if (Character && !Character->IsLocallyControlled())
|
if (Character && !Character->IsLocallyControlled())
|
||||||
{
|
{
|
||||||
Character->PlayThrowGrenadeMontage();
|
Character->PlayThrowGrenadeMontage();
|
||||||
AttachActorToLeftHand(PrimaryWeapon);
|
AttachActorToLeftHand(EquippedWeapon);
|
||||||
ShowAttachedGrenade(true);
|
ShowAttachedGrenade(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -585,12 +572,12 @@ void UCombatComponent::HandleReload()
|
||||||
|
|
||||||
int32 UCombatComponent::AmountToReload()
|
int32 UCombatComponent::AmountToReload()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return 0;
|
if (EquippedWeapon == nullptr) return 0;
|
||||||
int32 RoomInMag = PrimaryWeapon->GetMagCapacity() - PrimaryWeapon->GetAmmo();
|
int32 RoomInMag = EquippedWeapon->GetMagCapacity() - EquippedWeapon->GetAmmo();
|
||||||
|
|
||||||
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
|
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
|
||||||
{
|
{
|
||||||
int32 AmountCarried = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
|
int32 AmountCarried = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
|
||||||
int32 Least = FMath::Min(RoomInMag, AmountCarried);
|
int32 Least = FMath::Min(RoomInMag, AmountCarried);
|
||||||
return FMath::Clamp(RoomInMag, 0, Least);
|
return FMath::Clamp(RoomInMag, 0, Least);
|
||||||
}
|
}
|
||||||
|
@ -600,12 +587,12 @@ int32 UCombatComponent::AmountToReload()
|
||||||
void UCombatComponent::ThrowGrenade()
|
void UCombatComponent::ThrowGrenade()
|
||||||
{
|
{
|
||||||
if (Grenades == 0) return;
|
if (Grenades == 0) return;
|
||||||
if (CombatState != ECombatState::ECS_Unoccupied || PrimaryWeapon == nullptr) return;
|
if (CombatState != ECombatState::ECS_Unoccupied || EquippedWeapon == nullptr) return;
|
||||||
CombatState = ECombatState::ECS_ThrowingGrenade;
|
CombatState = ECombatState::ECS_ThrowingGrenade;
|
||||||
if (Character)
|
if (Character)
|
||||||
{
|
{
|
||||||
Character->PlayThrowGrenadeMontage();
|
Character->PlayThrowGrenadeMontage();
|
||||||
AttachActorToLeftHand(PrimaryWeapon);
|
AttachActorToLeftHand(EquippedWeapon);
|
||||||
ShowAttachedGrenade(true);
|
ShowAttachedGrenade(true);
|
||||||
}
|
}
|
||||||
if (Character && !Character->HasAuthority())
|
if (Character && !Character->HasAuthority())
|
||||||
|
@ -626,27 +613,27 @@ void UCombatComponent::ServerThrowGrenade_Implementation()
|
||||||
if (Character)
|
if (Character)
|
||||||
{
|
{
|
||||||
Character->PlayThrowGrenadeMontage();
|
Character->PlayThrowGrenadeMontage();
|
||||||
AttachActorToLeftHand(PrimaryWeapon);
|
AttachActorToLeftHand(EquippedWeapon);
|
||||||
ShowAttachedGrenade(true);
|
ShowAttachedGrenade(true);
|
||||||
}
|
}
|
||||||
Grenades = FMath::Clamp(Grenades -1, 0, MaxGrenades);
|
Grenades = FMath::Clamp(Grenades -1, 0, MaxGrenades);
|
||||||
UpdateHUDGrenades();
|
UpdateHUDGrenades();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::OnRep_Grenades()
|
|
||||||
{
|
|
||||||
UpdateHUDGrenades();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UCombatComponent::UpdateHUDGrenades()
|
void UCombatComponent::UpdateHUDGrenades()
|
||||||
{
|
{
|
||||||
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
|
||||||
if (Controller)
|
if (Controller)
|
||||||
{
|
{
|
||||||
Controller->SetHUDGrenades(Grenades);
|
Controller->SetHUDGrenades(Grenades);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UCombatComponent::ShouldSwapWeapons()
|
||||||
|
{
|
||||||
|
return EquippedWeapon != nullptr && SecondaryWeapon != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade)
|
void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade)
|
||||||
{
|
{
|
||||||
if (Character && Character->GetAttachedGrenade())
|
if (Character && Character->GetAttachedGrenade())
|
||||||
|
@ -655,6 +642,30 @@ void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::OnRep_EquippedWeapon()
|
||||||
|
{
|
||||||
|
if (EquippedWeapon && Character)
|
||||||
|
{
|
||||||
|
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
|
||||||
|
AttachActorToRightHand(EquippedWeapon);
|
||||||
|
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
|
||||||
|
Character->bUseControllerRotationYaw = true;
|
||||||
|
PlayEquipWeaponSound(EquippedWeapon);
|
||||||
|
EquippedWeapon->EnableCustomDepth(false);
|
||||||
|
EquippedWeapon->SetHUDAmmo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCombatComponent::OnRep_SecondaryWeapon()
|
||||||
|
{
|
||||||
|
if (SecondaryWeapon && Character)
|
||||||
|
{
|
||||||
|
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
|
||||||
|
AttachActorToBackpack(SecondaryWeapon);
|
||||||
|
PlayEquipWeaponSound(EquippedWeapon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
|
void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
|
||||||
{
|
{
|
||||||
FVector2D ViewportSize;
|
FVector2D ViewportSize;
|
||||||
|
@ -714,13 +725,13 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime)
|
||||||
HUD = HUD == nullptr ? Cast<ABlasterHUD>(Controller->GetHUD()) : HUD;
|
HUD = HUD == nullptr ? Cast<ABlasterHUD>(Controller->GetHUD()) : HUD;
|
||||||
if (HUD)
|
if (HUD)
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon)
|
if (EquippedWeapon)
|
||||||
{
|
{
|
||||||
HUDPackage.CrosshairsCenter = PrimaryWeapon->CrosshairsCenter;
|
HUDPackage.CrosshairsCenter = EquippedWeapon->CrosshairsCenter;
|
||||||
HUDPackage.CrosshairsLeft = PrimaryWeapon->CrosshairsLeft;
|
HUDPackage.CrosshairsLeft = EquippedWeapon->CrosshairsLeft;
|
||||||
HUDPackage.CrosshairsRight = PrimaryWeapon->CrosshairsRight;
|
HUDPackage.CrosshairsRight = EquippedWeapon->CrosshairsRight;
|
||||||
HUDPackage.CrosshairsBottom = PrimaryWeapon->CrosshairsBottom;
|
HUDPackage.CrosshairsBottom = EquippedWeapon->CrosshairsBottom;
|
||||||
HUDPackage.CrosshairsTop = PrimaryWeapon->CrosshairsTop;
|
HUDPackage.CrosshairsTop = EquippedWeapon->CrosshairsTop;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -774,11 +785,11 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime)
|
||||||
|
|
||||||
void UCombatComponent::InterpFOV(float DeltaTime)
|
void UCombatComponent::InterpFOV(float DeltaTime)
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return;
|
if (EquippedWeapon == nullptr) return;
|
||||||
|
|
||||||
if (bAiming)
|
if (bAiming)
|
||||||
{
|
{
|
||||||
CurrentFOV = FMath::FInterpTo(CurrentFOV, PrimaryWeapon->GetZoomedFOV(), DeltaTime, PrimaryWeapon->GetZoomInterpSpeed());
|
CurrentFOV = FMath::FInterpTo(CurrentFOV, EquippedWeapon->GetZoomedFOV(), DeltaTime, EquippedWeapon->GetZoomInterpSpeed());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -792,14 +803,14 @@ void UCombatComponent::InterpFOV(float DeltaTime)
|
||||||
|
|
||||||
void UCombatComponent::SetAiming(bool bIsAiming)
|
void UCombatComponent::SetAiming(bool bIsAiming)
|
||||||
{
|
{
|
||||||
if (Character == nullptr || PrimaryWeapon == nullptr) return;
|
if (Character == nullptr || EquippedWeapon == nullptr) return;
|
||||||
bAiming = bIsAiming;
|
bAiming = bIsAiming;
|
||||||
ServerSetAiming(bIsAiming);
|
ServerSetAiming(bIsAiming);
|
||||||
if (Character)
|
if (Character)
|
||||||
{
|
{
|
||||||
Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed;
|
Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed;
|
||||||
}
|
}
|
||||||
if (Character->IsLocallyControlled() && PrimaryWeapon->IsSniper())
|
if (Character->IsLocallyControlled() && EquippedWeapon->IsSniper())
|
||||||
{
|
{
|
||||||
Character->ShowSniperScopeWidget(bIsAiming);
|
Character->ShowSniperScopeWidget(bIsAiming);
|
||||||
}
|
}
|
||||||
|
@ -815,20 +826,12 @@ void UCombatComponent::ServerSetAiming_Implementation(bool bIsAiming)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCombatComponent::OnRep_Aiming()
|
|
||||||
{
|
|
||||||
if (Character && Character->IsLocallyControlled())
|
|
||||||
{
|
|
||||||
bAiming = bAimButtonPressed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UCombatComponent::CanFire()
|
bool UCombatComponent::CanFire()
|
||||||
{
|
{
|
||||||
if (PrimaryWeapon == nullptr) return false;
|
if (EquippedWeapon == nullptr) return false;
|
||||||
if (PrimaryWeapon->IsEmpty()) return false;
|
if (EquippedWeapon->IsEmpty()) return false;
|
||||||
if (!bCanFire) return false;
|
if (!bCanFire) return false;
|
||||||
if (CombatState == ECombatState::ECS_Reloading && PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true;
|
if (CombatState == ECombatState::ECS_Reloading && EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true;
|
||||||
if (bLocallyReloading) return false;
|
if (bLocallyReloading) return false;
|
||||||
return CombatState == ECombatState::ECS_Unoccupied;
|
return CombatState == ECombatState::ECS_Unoccupied;
|
||||||
}
|
}
|
||||||
|
@ -843,8 +846,8 @@ void UCombatComponent::OnRep_CarriedAmmo()
|
||||||
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
Controller->SetHUDCarriedAmmo(CarriedAmmo);
|
||||||
}
|
}
|
||||||
bool bJumpToShotgunEnd = CombatState == ECombatState::ECS_Reloading &&
|
bool bJumpToShotgunEnd = CombatState == ECombatState::ECS_Reloading &&
|
||||||
PrimaryWeapon != nullptr &&
|
EquippedWeapon != nullptr &&
|
||||||
PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun &&
|
EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun &&
|
||||||
CarriedAmmo == 0;
|
CarriedAmmo == 0;
|
||||||
|
|
||||||
if (bJumpToShotgunEnd)
|
if (bJumpToShotgunEnd)
|
||||||
|
|
|
@ -62,15 +62,18 @@ protected:
|
||||||
void ServerSetAiming(bool bIsAiming);
|
void ServerSetAiming(bool bIsAiming);
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
void OnRep_PrimaryWeapon();
|
void OnRep_EquippedWeapon();
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
void OnRep_SecondaryWeapon();
|
void OnRep_SecondaryWeapon();
|
||||||
|
|
||||||
void Fire();
|
void Fire();
|
||||||
void FireProjectileWeapon();
|
void FireProjectileWeapon();
|
||||||
void FireHitScanWeapon();
|
void FireHitScanWeapon();
|
||||||
void FireShotgun();
|
void FireShotgun();
|
||||||
|
void LocalFire(const FVector_NetQuantize& TraceHitTarget);
|
||||||
|
void ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets);
|
||||||
|
|
||||||
UFUNCTION(Server, Reliable, WithValidation)
|
UFUNCTION(Server, Reliable, WithValidation)
|
||||||
void ServerFire(const FVector_NetQuantize& TraceHitTarget, float FireDelay);
|
void ServerFire(const FVector_NetQuantize& TraceHitTarget, float FireDelay);
|
||||||
|
|
||||||
|
@ -101,12 +104,12 @@ protected:
|
||||||
UPROPERTY(EditAnywhere)
|
UPROPERTY(EditAnywhere)
|
||||||
TSubclassOf<class AProjectile> GrenadeClass;
|
TSubclassOf<class AProjectile> GrenadeClass;
|
||||||
|
|
||||||
void DropPrimaryWeapon();
|
void DropEquippedWeapon();
|
||||||
void AttachActorToRightHand(AActor* ActorToAttach);
|
void AttachActorToRightHand(AActor* ActorToAttach);
|
||||||
void AttachActorToLeftHand(AActor* ActorToAttach);
|
void AttachActorToLeftHand(AActor* ActorToAttach);
|
||||||
void AttachActorToBackpack(AActor* ActorToAttach);
|
void AttachActorToBackpack(AActor* ActorToAttach);
|
||||||
void UpdateCarriedAmmo();
|
void UpdateCarriedAmmo();
|
||||||
void PlayEquipWeaponSound(const AWeapon* Weapon);
|
void PlayEquipWeaponSound(const AWeapon* WeaponToEquip);
|
||||||
void ReloadEmptyWeapon();
|
void ReloadEmptyWeapon();
|
||||||
void ShowAttachedGrenade(bool bShowGrenade);
|
void ShowAttachedGrenade(bool bShowGrenade);
|
||||||
void EquipPrimaryWeapon(AWeapon* WeaponToEquip);
|
void EquipPrimaryWeapon(AWeapon* WeaponToEquip);
|
||||||
|
@ -121,10 +124,10 @@ private:
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
ABlasterHUD* HUD;
|
ABlasterHUD* HUD;
|
||||||
|
|
||||||
UPROPERTY(ReplicatedUsing=OnRep_PrimaryWeapon)
|
UPROPERTY(ReplicatedUsing = OnRep_EquippedWeapon)
|
||||||
AWeapon* PrimaryWeapon;
|
AWeapon* EquippedWeapon;
|
||||||
|
|
||||||
UPROPERTY(ReplicatedUsing=OnRep_SecondaryWeapon)
|
UPROPERTY(ReplicatedUsing = OnRep_SecondaryWeapon)
|
||||||
AWeapon* SecondaryWeapon;
|
AWeapon* SecondaryWeapon;
|
||||||
|
|
||||||
UPROPERTY(ReplicatedUsing = OnRep_Aiming)
|
UPROPERTY(ReplicatedUsing = OnRep_Aiming)
|
||||||
|
@ -148,6 +151,9 @@ private:
|
||||||
float CrosshairInAirFactor;
|
float CrosshairInAirFactor;
|
||||||
float CrosshairAimFactor;
|
float CrosshairAimFactor;
|
||||||
float CrosshairShootingFactor;
|
float CrosshairShootingFactor;
|
||||||
|
|
||||||
|
FVector HitTarget;
|
||||||
|
|
||||||
FHUDPackage HUDPackage;
|
FHUDPackage HUDPackage;
|
||||||
|
|
||||||
// Aiming and FOV
|
// Aiming and FOV
|
||||||
|
@ -164,8 +170,7 @@ private:
|
||||||
float ZoomInterpSpeed = 20.f;
|
float ZoomInterpSpeed = 20.f;
|
||||||
|
|
||||||
void InterpFOV(float DeltaTime);
|
void InterpFOV(float DeltaTime);
|
||||||
|
|
||||||
FVector HitTarget;
|
|
||||||
|
|
||||||
// Automatic fire
|
// Automatic fire
|
||||||
FTimerHandle FireTimer;
|
FTimerHandle FireTimer;
|
||||||
|
@ -173,13 +178,11 @@ private:
|
||||||
|
|
||||||
void StartFireTimer();
|
void StartFireTimer();
|
||||||
void FireTimerFinished();
|
void FireTimerFinished();
|
||||||
void LocalFire(const FVector_NetQuantize& TraceHitTarget);
|
|
||||||
void ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets);
|
|
||||||
|
|
||||||
bool CanFire();
|
bool CanFire();
|
||||||
|
|
||||||
// Carried ammo for the currently equipped weapon
|
// Carried ammo for the currently equipped weapon
|
||||||
UPROPERTY(ReplicatedUsing=OnRep_CarriedAmmo)
|
UPROPERTY(ReplicatedUsing = OnRep_CarriedAmmo)
|
||||||
int32 CarriedAmmo;
|
int32 CarriedAmmo;
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
|
|
|
@ -13,110 +13,6 @@ ULagCompensationComponent::ULagCompensationComponent()
|
||||||
PrimaryComponentTick.bCanEverTick = true;
|
PrimaryComponentTick.bCanEverTick = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ULagCompensationComponent::ServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
|
|
||||||
const FVector_NetQuantize& HitLocation, float HitTime, AWeapon* DamageCauser)
|
|
||||||
{
|
|
||||||
const FServerSideRewindResult Confirm = ServerSideRewind(HitCharacter, TraceStart, HitLocation, HitTime);
|
|
||||||
|
|
||||||
if (Character && HitCharacter && DamageCauser && Confirm.bHitConfirmed)
|
|
||||||
{
|
|
||||||
UGameplayStatics::ApplyDamage(
|
|
||||||
HitCharacter,
|
|
||||||
DamageCauser->GetDamage(),
|
|
||||||
Character->Controller,
|
|
||||||
DamageCauser,
|
|
||||||
UDamageType::StaticClass()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ULagCompensationComponent::ProjectileServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
|
|
||||||
const FVector_NetQuantize100& InitialVelocity, float HitTime)
|
|
||||||
{
|
|
||||||
const FServerSideRewindResult Confirm = ProjectilServerSideRewind(HitCharacter, TraceStart, InitialVelocity, HitTime);
|
|
||||||
|
|
||||||
if (Character && HitCharacter && Confirm.bHitConfirmed)
|
|
||||||
{
|
|
||||||
UGameplayStatics::ApplyDamage(
|
|
||||||
HitCharacter,
|
|
||||||
Character->GetPrimaryWeapon()->GetDamage(),
|
|
||||||
Character->Controller,
|
|
||||||
Character->GetPrimaryWeapon(),
|
|
||||||
UDamageType::StaticClass()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ULagCompensationComponent::ShotgunServerScoreRequest_Implementation(const TArray<ABlasterCharacter*>& HitCharacters, const FVector_NetQuantize& TraceStart,
|
|
||||||
const TArray<FVector_NetQuantize>& HitLocations, float HitTime)
|
|
||||||
{
|
|
||||||
FShotgunServerSideRewindResult Confirm = ShotgunServerSideRewind(HitCharacters, TraceStart, HitLocations, HitTime);
|
|
||||||
|
|
||||||
for (auto& HitCharacter : HitCharacters)
|
|
||||||
{
|
|
||||||
if (HitCharacter == nullptr || Character == nullptr || HitCharacter->GetPrimaryWeapon() == nullptr) continue;
|
|
||||||
float TotalDamage = 0.f;
|
|
||||||
if (Confirm.Headshots.Contains(HitCharacter))
|
|
||||||
{
|
|
||||||
TotalDamage += Confirm.Headshots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
|
|
||||||
}
|
|
||||||
if (Confirm.BodyShots.Contains(HitCharacter))
|
|
||||||
{
|
|
||||||
TotalDamage += Confirm.BodyShots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
|
|
||||||
}
|
|
||||||
|
|
||||||
UGameplayStatics::ApplyDamage(
|
|
||||||
HitCharacter,
|
|
||||||
TotalDamage,
|
|
||||||
Character->Controller,
|
|
||||||
Character->GetPrimaryWeapon(),
|
|
||||||
UDamageType::StaticClass()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ULagCompensationComponent::SaveFramePackage()
|
|
||||||
{
|
|
||||||
if (Character == nullptr || !Character->HasAuthority()) return;
|
|
||||||
if (FrameHistory.Num() <= 1)
|
|
||||||
{
|
|
||||||
FFramePackage ThisFrame;
|
|
||||||
SaveFramePackage(ThisFrame);
|
|
||||||
FrameHistory.AddHead(ThisFrame);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
|
|
||||||
while (HistoryLength > MaxRecordTime)
|
|
||||||
{
|
|
||||||
FrameHistory.RemoveNode(FrameHistory.GetTail());
|
|
||||||
HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
|
|
||||||
}
|
|
||||||
FFramePackage ThisFrame;
|
|
||||||
SaveFramePackage(ThisFrame);
|
|
||||||
FrameHistory.AddHead(ThisFrame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ULagCompensationComponent::SaveFramePackage(FFramePackage& Package)
|
|
||||||
{
|
|
||||||
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : Character;
|
|
||||||
if (Character)
|
|
||||||
{
|
|
||||||
Package.Time = GetWorld()->GetTimeSeconds();
|
|
||||||
Package.Character = Character;
|
|
||||||
for (auto& BoxPair : Character->HitCollisionBoxes)
|
|
||||||
{
|
|
||||||
FBoxInformation BoxInformation;
|
|
||||||
BoxInformation.Location = BoxPair.Value->GetComponentLocation();
|
|
||||||
BoxInformation.Rotation = BoxPair.Value->GetComponentRotation();
|
|
||||||
BoxInformation.BoxExtend = BoxPair.Value->GetScaledBoxExtent();
|
|
||||||
|
|
||||||
Package.HitBoxInfo.Add(BoxPair.Key, BoxInformation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FFramePackage ULagCompensationComponent::InterpBetweenFrames(const FFramePackage& OlderFrame, const FFramePackage& YoungerFrame, float HitTime)
|
FFramePackage ULagCompensationComponent::InterpBetweenFrames(const FFramePackage& OlderFrame, const FFramePackage& YoungerFrame, float HitTime)
|
||||||
{
|
{
|
||||||
const float Distance = YoungerFrame.Time - OlderFrame.Time;
|
const float Distance = YoungerFrame.Time - OlderFrame.Time;
|
||||||
|
@ -134,7 +30,7 @@ FFramePackage ULagCompensationComponent::InterpBetweenFrames(const FFramePackage
|
||||||
FBoxInformation InterpBoxInfo;
|
FBoxInformation InterpBoxInfo;
|
||||||
InterpBoxInfo.Location = FMath::VInterpTo(OlderBox.Location, YoungerBox.Location, 1.f, InterpFraction);
|
InterpBoxInfo.Location = FMath::VInterpTo(OlderBox.Location, YoungerBox.Location, 1.f, InterpFraction);
|
||||||
InterpBoxInfo.Rotation = FMath::RInterpTo(OlderBox.Rotation, YoungerBox.Rotation, 1.f, InterpFraction);
|
InterpBoxInfo.Rotation = FMath::RInterpTo(OlderBox.Rotation, YoungerBox.Rotation, 1.f, InterpFraction);
|
||||||
InterpBoxInfo.BoxExtend = OlderBox.BoxExtend;
|
InterpBoxInfo.BoxExtent = YoungerBox.BoxExtent;
|
||||||
|
|
||||||
InterpFramePackage.HitBoxInfo.Add(BoxInfoName, InterpBoxInfo);
|
InterpFramePackage.HitBoxInfo.Add(BoxInfoName, InterpBoxInfo);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +63,6 @@ FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackag
|
||||||
TraceEnd,
|
TraceEnd,
|
||||||
ECC_HitBox
|
ECC_HitBox
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ConfirmHitResult.bBlockingHit) // we hit the head, return early
|
if (ConfirmHitResult.bBlockingHit) // we hit the head, return early
|
||||||
{
|
{
|
||||||
ResetHitBoxes(HitCharacter, CurrentFrame);
|
ResetHitBoxes(HitCharacter, CurrentFrame);
|
||||||
|
@ -322,7 +217,7 @@ FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable collision for all boxes, then disable for head box
|
// Enable collision for all boxes, then disable for head box
|
||||||
for (auto& Frame :FramePackages)
|
for (auto& Frame : FramePackages)
|
||||||
{
|
{
|
||||||
for (auto& HitBoxPair : Frame.Character->HitCollisionBoxes)
|
for (auto& HitBoxPair : Frame.Character->HitCollisionBoxes)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +272,6 @@ FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(cons
|
||||||
void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage)
|
void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage)
|
||||||
{
|
{
|
||||||
if (HitCharacter == nullptr) return;
|
if (HitCharacter == nullptr) return;
|
||||||
|
|
||||||
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
|
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
|
||||||
{
|
{
|
||||||
if (HitBoxPair.Value != nullptr)
|
if (HitBoxPair.Value != nullptr)
|
||||||
|
@ -385,8 +279,7 @@ void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacte
|
||||||
FBoxInformation BoxInfo;
|
FBoxInformation BoxInfo;
|
||||||
BoxInfo.Location = HitBoxPair.Value->GetComponentLocation();
|
BoxInfo.Location = HitBoxPair.Value->GetComponentLocation();
|
||||||
BoxInfo.Rotation = HitBoxPair.Value->GetComponentRotation();
|
BoxInfo.Rotation = HitBoxPair.Value->GetComponentRotation();
|
||||||
BoxInfo.BoxExtend = HitBoxPair.Value->GetScaledBoxExtent();
|
BoxInfo.BoxExtent = HitBoxPair.Value->GetScaledBoxExtent();
|
||||||
|
|
||||||
OutFramePackage.HitBoxInfo.Add(HitBoxPair.Key, BoxInfo);
|
OutFramePackage.HitBoxInfo.Add(HitBoxPair.Key, BoxInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,14 +288,13 @@ void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacte
|
||||||
void ULagCompensationComponent::MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
|
void ULagCompensationComponent::MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
|
||||||
{
|
{
|
||||||
if (HitCharacter == nullptr) return;
|
if (HitCharacter == nullptr) return;
|
||||||
|
|
||||||
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
|
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
|
||||||
{
|
{
|
||||||
if (HitBoxPair.Value != nullptr)
|
if (HitBoxPair.Value != nullptr)
|
||||||
{
|
{
|
||||||
HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
|
HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
|
||||||
HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
|
HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
|
||||||
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtend);
|
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,14 +302,13 @@ void ULagCompensationComponent::MoveBoxes(ABlasterCharacter* HitCharacter, const
|
||||||
void ULagCompensationComponent::ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
|
void ULagCompensationComponent::ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
|
||||||
{
|
{
|
||||||
if (HitCharacter == nullptr) return;
|
if (HitCharacter == nullptr) return;
|
||||||
|
|
||||||
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
|
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
|
||||||
{
|
{
|
||||||
if (HitBoxPair.Value != nullptr)
|
if (HitBoxPair.Value != nullptr)
|
||||||
{
|
{
|
||||||
HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
|
HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
|
||||||
HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
|
HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
|
||||||
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtend);
|
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtent);
|
||||||
HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,7 +321,7 @@ void ULagCompensationComponent::ShowFramePackage(const FFramePackage& Package, c
|
||||||
DrawDebugBox(
|
DrawDebugBox(
|
||||||
GetWorld(),
|
GetWorld(),
|
||||||
BoxInfo.Value.Location,
|
BoxInfo.Value.Location,
|
||||||
BoxInfo.Value.BoxExtend,
|
BoxInfo.Value.BoxExtent,
|
||||||
FQuat(BoxInfo.Value.Rotation),
|
FQuat(BoxInfo.Value.Rotation),
|
||||||
Color,
|
Color,
|
||||||
false,
|
false,
|
||||||
|
@ -446,7 +337,7 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar
|
||||||
return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
|
return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
FServerSideRewindResult ULagCompensationComponent::ProjectilServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
|
FServerSideRewindResult ULagCompensationComponent::ProjectileServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
|
||||||
const FVector_NetQuantize100& InitialVelocity, float HitTime)
|
const FVector_NetQuantize100& InitialVelocity, float HitTime)
|
||||||
{
|
{
|
||||||
const FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime);
|
const FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime);
|
||||||
|
@ -471,9 +362,7 @@ FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitC
|
||||||
HitCharacter->GetLagCompensation() == nullptr ||
|
HitCharacter->GetLagCompensation() == nullptr ||
|
||||||
HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr ||
|
HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr ||
|
||||||
HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr;
|
HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr;
|
||||||
|
|
||||||
if (bReturn) FFramePackage();
|
if (bReturn) FFramePackage();
|
||||||
|
|
||||||
// Frame package that we check to verify a hit
|
// Frame package that we check to verify a hit
|
||||||
FFramePackage FrameToCheck;
|
FFramePackage FrameToCheck;
|
||||||
bool bShouldInterpolate = true;
|
bool bShouldInterpolate = true;
|
||||||
|
@ -512,17 +401,76 @@ FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitC
|
||||||
FrameToCheck = Older->GetValue();
|
FrameToCheck = Older->GetValue();
|
||||||
bShouldInterpolate = false;
|
bShouldInterpolate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr?
|
if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr?
|
||||||
{
|
{
|
||||||
// Interpolate between Younger and Older
|
// Interpolate between Younger and Older
|
||||||
FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
|
FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameToCheck.Character = HitCharacter;
|
FrameToCheck.Character = HitCharacter;
|
||||||
|
|
||||||
return FrameToCheck;
|
return FrameToCheck;
|
||||||
}
|
}
|
||||||
|
void ULagCompensationComponent::ServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
|
||||||
|
const FVector_NetQuantize& HitLocation, float HitTime, AWeapon* DamageCauser)
|
||||||
|
{
|
||||||
|
const FServerSideRewindResult Confirm = ServerSideRewind(HitCharacter, TraceStart, HitLocation, HitTime);
|
||||||
|
|
||||||
|
if (Character && HitCharacter && DamageCauser && Confirm.bHitConfirmed)
|
||||||
|
{
|
||||||
|
UGameplayStatics::ApplyDamage(
|
||||||
|
HitCharacter,
|
||||||
|
DamageCauser->GetDamage(),
|
||||||
|
Character->Controller,
|
||||||
|
DamageCauser,
|
||||||
|
UDamageType::StaticClass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULagCompensationComponent::ProjectileServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
|
||||||
|
const FVector_NetQuantize100& InitialVelocity, float HitTime)
|
||||||
|
{
|
||||||
|
const FServerSideRewindResult Confirm = ProjectileServerSideRewind(HitCharacter, TraceStart, InitialVelocity, HitTime);
|
||||||
|
|
||||||
|
if (Character && HitCharacter && Confirm.bHitConfirmed)
|
||||||
|
{
|
||||||
|
UGameplayStatics::ApplyDamage(
|
||||||
|
HitCharacter,
|
||||||
|
Character->GetPrimaryWeapon()->GetDamage(),
|
||||||
|
Character->Controller,
|
||||||
|
Character->GetPrimaryWeapon(),
|
||||||
|
UDamageType::StaticClass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULagCompensationComponent::ShotgunServerScoreRequest_Implementation(const TArray<ABlasterCharacter*>& HitCharacters, const FVector_NetQuantize& TraceStart,
|
||||||
|
const TArray<FVector_NetQuantize>& HitLocations, float HitTime)
|
||||||
|
{
|
||||||
|
FShotgunServerSideRewindResult Confirm = ShotgunServerSideRewind(HitCharacters, TraceStart, HitLocations, HitTime);
|
||||||
|
|
||||||
|
for (auto& HitCharacter : HitCharacters)
|
||||||
|
{
|
||||||
|
if (HitCharacter == nullptr || Character == nullptr || HitCharacter->GetPrimaryWeapon() == nullptr) continue;
|
||||||
|
float TotalDamage = 0.f;
|
||||||
|
if (Confirm.Headshots.Contains(HitCharacter))
|
||||||
|
{
|
||||||
|
TotalDamage += Confirm.Headshots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
|
||||||
|
}
|
||||||
|
if (Confirm.BodyShots.Contains(HitCharacter))
|
||||||
|
{
|
||||||
|
TotalDamage += Confirm.BodyShots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
|
||||||
|
}
|
||||||
|
|
||||||
|
UGameplayStatics::ApplyDamage(
|
||||||
|
HitCharacter,
|
||||||
|
TotalDamage,
|
||||||
|
Character->Controller,
|
||||||
|
Character->GetPrimaryWeapon(),
|
||||||
|
UDamageType::StaticClass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ULagCompensationComponent::EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled)
|
void ULagCompensationComponent::EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled)
|
||||||
{
|
{
|
||||||
|
@ -538,3 +486,44 @@ void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickTy
|
||||||
|
|
||||||
SaveFramePackage();
|
SaveFramePackage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ULagCompensationComponent::SaveFramePackage()
|
||||||
|
{
|
||||||
|
if (Character == nullptr || !Character->HasAuthority()) return;
|
||||||
|
if (FrameHistory.Num() <= 1)
|
||||||
|
{
|
||||||
|
FFramePackage ThisFrame;
|
||||||
|
SaveFramePackage(ThisFrame);
|
||||||
|
FrameHistory.AddHead(ThisFrame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
|
||||||
|
while (HistoryLength > MaxRecordTime)
|
||||||
|
{
|
||||||
|
FrameHistory.RemoveNode(FrameHistory.GetTail());
|
||||||
|
HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
|
||||||
|
}
|
||||||
|
FFramePackage ThisFrame;
|
||||||
|
SaveFramePackage(ThisFrame);
|
||||||
|
FrameHistory.AddHead(ThisFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULagCompensationComponent::SaveFramePackage(FFramePackage& Package)
|
||||||
|
{
|
||||||
|
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : Character;
|
||||||
|
if (Character)
|
||||||
|
{
|
||||||
|
Package.Time = GetWorld()->GetTimeSeconds();
|
||||||
|
Package.Character = Character;
|
||||||
|
for (auto& BoxPair : Character->HitCollisionBoxes)
|
||||||
|
{
|
||||||
|
FBoxInformation BoxInformation;
|
||||||
|
BoxInformation.Location = BoxPair.Value->GetComponentLocation();
|
||||||
|
BoxInformation.Rotation = BoxPair.Value->GetComponentRotation();
|
||||||
|
BoxInformation.BoxExtent = BoxPair.Value->GetScaledBoxExtent();
|
||||||
|
Package.HitBoxInfo.Add(BoxPair.Key, BoxInformation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct FBoxInformation
|
||||||
FRotator Rotation;
|
FRotator Rotation;
|
||||||
|
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FVector BoxExtend;
|
FVector BoxExtent;
|
||||||
};
|
};
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
|
@ -81,7 +81,7 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// Projectiles
|
// Projectiles
|
||||||
FServerSideRewindResult ProjectilServerSideRewind(
|
FServerSideRewindResult ProjectileServerSideRewind(
|
||||||
ABlasterCharacter* HitCharacter,
|
ABlasterCharacter* HitCharacter,
|
||||||
const FVector_NetQuantize& TraceStart,
|
const FVector_NetQuantize& TraceStart,
|
||||||
const FVector_NetQuantize100& InitialVelocity,
|
const FVector_NetQuantize100& InitialVelocity,
|
||||||
|
|
|
@ -88,9 +88,9 @@ void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedChara
|
||||||
{
|
{
|
||||||
PlayersCurrentlyInTheLead.Add(LeadPlayer);
|
PlayersCurrentlyInTheLead.Add(LeadPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttackerPlayerState->IncreaseScore(1.f);
|
AttackerPlayerState->IncreaseScore(1.f);
|
||||||
BlasterGameState->UpdateTopScore(AttackerPlayerState);
|
BlasterGameState->UpdateTopScore(AttackerPlayerState);
|
||||||
|
|
||||||
if (BlasterGameState->TopScoringPlayers.Contains(AttackerPlayerState))
|
if (BlasterGameState->TopScoringPlayers.Contains(AttackerPlayerState))
|
||||||
{
|
{
|
||||||
ABlasterCharacter* Leader = Cast<ABlasterCharacter>(AttackerPlayerState->GetPawn());
|
ABlasterCharacter* Leader = Cast<ABlasterCharacter>(AttackerPlayerState->GetPawn());
|
||||||
|
@ -99,6 +99,7 @@ void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedChara
|
||||||
Leader->MulticastGainedTheLead();
|
Leader->MulticastGainedTheLead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 i = 0; i < PlayersCurrentlyInTheLead.Num(); i++)
|
for (int32 i = 0; i < PlayersCurrentlyInTheLead.Num(); i++)
|
||||||
{
|
{
|
||||||
if (!BlasterGameState->TopScoringPlayers.Contains(PlayersCurrentlyInTheLead[i]))
|
if (!BlasterGameState->TopScoringPlayers.Contains(PlayersCurrentlyInTheLead[i]))
|
||||||
|
|
|
@ -24,7 +24,7 @@ void ABlasterGameState::UpdateTopScore(ABlasterPlayerState* ScoringPlayer)
|
||||||
{
|
{
|
||||||
TopScoringPlayers.AddUnique(ScoringPlayer);
|
TopScoringPlayers.AddUnique(ScoringPlayer);
|
||||||
}
|
}
|
||||||
else if (ScoringPlayer->GetScore() < TopScore)
|
else if (ScoringPlayer->GetScore() > TopScore)
|
||||||
{
|
{
|
||||||
TopScoringPlayers.Empty();
|
TopScoringPlayers.Empty();
|
||||||
TopScoringPlayers.AddUnique(ScoringPlayer);
|
TopScoringPlayers.AddUnique(ScoringPlayer);
|
||||||
|
|
|
@ -28,15 +28,6 @@ void ABlasterPlayerController::BeginPlay()
|
||||||
ServerCheckMatchState();
|
ServerCheckMatchState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::SetupInputComponent()
|
|
||||||
{
|
|
||||||
Super::SetupInputComponent();
|
|
||||||
|
|
||||||
if (InputComponent == nullptr) return;
|
|
||||||
|
|
||||||
InputComponent->BindAction("Quit", IE_Pressed, this, &ABlasterPlayerController::ShowReturnToMainMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
void ABlasterPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||||
{
|
{
|
||||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||||
|
@ -72,11 +63,10 @@ void ABlasterPlayerController::Tick(float DeltaTime)
|
||||||
|
|
||||||
void ABlasterPlayerController::CheckPing(float DeltaTime)
|
void ABlasterPlayerController::CheckPing(float DeltaTime)
|
||||||
{
|
{
|
||||||
|
if (HasAuthority()) return;
|
||||||
HighPingRunningTime += DeltaTime;
|
HighPingRunningTime += DeltaTime;
|
||||||
if (HighPingRunningTime > CheckPingFrequency)
|
if (HighPingRunningTime > CheckPingFrequency)
|
||||||
{
|
{
|
||||||
HighPingRunningTime = 0.f;
|
|
||||||
|
|
||||||
PlayerState = PlayerState == nullptr ? GetPlayerState<APlayerState>() : PlayerState;
|
PlayerState = PlayerState == nullptr ? GetPlayerState<APlayerState>() : PlayerState;
|
||||||
if (PlayerState)
|
if (PlayerState)
|
||||||
{
|
{
|
||||||
|
@ -85,19 +75,18 @@ void ABlasterPlayerController::CheckPing(float DeltaTime)
|
||||||
HighPingWarning();
|
HighPingWarning();
|
||||||
PingAnimationRunningTime = 0.f;
|
PingAnimationRunningTime = 0.f;
|
||||||
ServerReportPingStatus(true);
|
ServerReportPingStatus(true);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ServerReportPingStatus(false);
|
ServerReportPingStatus(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
HighPingRunningTime = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bHighPingAnimationPlaying =
|
bool bHighPingAnimationPlaying =
|
||||||
BlasterHUD &&
|
BlasterHUD && BlasterHUD->CharacterOverlay &&
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->HighPingAnimation &&
|
BlasterHUD->CharacterOverlay->HighPingAnimation &&
|
||||||
BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation);
|
BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation);
|
||||||
|
|
||||||
if (bHighPingAnimationPlaying)
|
if (bHighPingAnimationPlaying)
|
||||||
{
|
{
|
||||||
PingAnimationRunningTime += DeltaTime;
|
PingAnimationRunningTime += DeltaTime;
|
||||||
|
@ -108,6 +97,27 @@ void ABlasterPlayerController::CheckPing(float DeltaTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::ShowReturnToMainMenu()
|
||||||
|
{
|
||||||
|
if (ReturnToMainMenuWidget == nullptr) return;
|
||||||
|
if (ReturnToMainMenu == nullptr)
|
||||||
|
{
|
||||||
|
ReturnToMainMenu = CreateWidget<UReturnToMainMenu>(this, ReturnToMainMenuWidget);
|
||||||
|
}
|
||||||
|
if (ReturnToMainMenu)
|
||||||
|
{
|
||||||
|
bReturnToMainMenuOpen = !bReturnToMainMenuOpen;
|
||||||
|
if (bReturnToMainMenuOpen)
|
||||||
|
{
|
||||||
|
ReturnToMainMenu->MenuSetup();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReturnToMainMenu->MenuTearDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Is the ping to high?
|
// Is the ping to high?
|
||||||
void ABlasterPlayerController::ServerReportPingStatus_Implementation(bool bHighPing)
|
void ABlasterPlayerController::ServerReportPingStatus_Implementation(bool bHighPing)
|
||||||
{
|
{
|
||||||
|
@ -160,6 +170,37 @@ void ABlasterPlayerController::CheckTimeSync(float DeltaTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::HighPingWarning()
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->HighPingImage &&
|
||||||
|
BlasterHUD->CharacterOverlay->HighPingAnimation;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(1.f);
|
||||||
|
BlasterHUD->CharacterOverlay->PlayAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation, 0.f, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::StopHighPingWarning()
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->HighPingImage &&
|
||||||
|
BlasterHUD->CharacterOverlay->HighPingAnimation;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(0.f);
|
||||||
|
if (BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation))
|
||||||
|
{
|
||||||
|
BlasterHUD->CharacterOverlay->StopAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::ServerCheckMatchState_Implementation()
|
void ABlasterPlayerController::ServerCheckMatchState_Implementation()
|
||||||
{
|
{
|
||||||
ABlasterGameMode* GameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
|
ABlasterGameMode* GameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
|
||||||
|
@ -292,7 +333,7 @@ void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bInitializeHUDWeaponAmmo = true;
|
bInitializeWeaponAmmo = true;
|
||||||
HUDWeaponAmmo = Ammo;
|
HUDWeaponAmmo = Ammo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,24 +356,6 @@ void ABlasterPlayerController::SetHUDCarriedAmmo(int32 Ammo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDGrenades(int32 Grenades)
|
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid = BlasterHUD &&
|
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->GrenadesAmount;
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
FString GrenadesText = FString::Printf(TEXT("%d"), Grenades);
|
|
||||||
BlasterHUD->CharacterOverlay->GrenadesAmount->SetText(FText::FromString(GrenadesText));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bInitializeGrenades = true;
|
|
||||||
HUDGrenades = Grenades;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDMatchCountdown(float CountdownTime)
|
void ABlasterPlayerController::SetHUDMatchCountdown(float CountdownTime)
|
||||||
{
|
{
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
@ -377,24 +400,31 @@ void ABlasterPlayerController::SetHUDAnnouncementCountdown(float CountdownTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABlasterPlayerController::SetHUDGrenades(int32 Grenades)
|
||||||
|
{
|
||||||
|
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
||||||
|
bool bHUDValid = BlasterHUD &&
|
||||||
|
BlasterHUD->CharacterOverlay &&
|
||||||
|
BlasterHUD->CharacterOverlay->GrenadesAmount;
|
||||||
|
if (bHUDValid)
|
||||||
|
{
|
||||||
|
FString GrenadesText = FString::Printf(TEXT("%d"), Grenades);
|
||||||
|
BlasterHUD->CharacterOverlay->GrenadesAmount->SetText(FText::FromString(GrenadesText));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bInitializeGrenades = true;
|
||||||
|
HUDGrenades = Grenades;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::SetHUDTime()
|
void ABlasterPlayerController::SetHUDTime()
|
||||||
{
|
{
|
||||||
float TimeLeft = 0.f;
|
float TimeLeft = 0.f;
|
||||||
if (MatchState == MatchState::WaitingToStart) TimeLeft = WarmupTime - GetServerTime(); // + LevelStartingTime;
|
if (MatchState == MatchState::WaitingToStart) TimeLeft = WarmupTime - GetServerTime(); // + LevelStartingTime;
|
||||||
else if (MatchState == MatchState::InProgress) TimeLeft = WarmupTime + MatchTime - GetServerTime(); // + LevelStartingTime;
|
else if (MatchState == MatchState::InProgress) TimeLeft = WarmupTime + MatchTime - GetServerTime(); // + LevelStartingTime;
|
||||||
else if (MatchState == MatchState::Cooldown) TimeLeft = WarmupTime + MatchTime + CooldownTime - GetServerTime(); // + LevelStartingTime;
|
else if (MatchState == MatchState::Cooldown) TimeLeft = WarmupTime + MatchTime + CooldownTime - GetServerTime(); // + LevelStartingTime;
|
||||||
|
|
||||||
uint32 SecondsLeft = FMath::CeilToInt(TimeLeft);
|
uint32 SecondsLeft = FMath::CeilToInt(TimeLeft);
|
||||||
|
|
||||||
if (HasAuthority())
|
|
||||||
{
|
|
||||||
BlasterGameMode = BlasterGameMode == nullptr ? Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this)) : BlasterGameMode;
|
|
||||||
if (BlasterGameMode)
|
|
||||||
{
|
|
||||||
SecondsLeft = FMath::CeilToInt(BlasterGameMode->GetCountdownTime());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CountdownInt != SecondsLeft)
|
if (CountdownInt != SecondsLeft)
|
||||||
{
|
{
|
||||||
if (MatchState == MatchState::WaitingToStart || MatchState == MatchState::Cooldown)
|
if (MatchState == MatchState::WaitingToStart || MatchState == MatchState::Cooldown)
|
||||||
|
@ -435,7 +465,8 @@ void ABlasterPlayerController::PollInit()
|
||||||
if (bInitializeScore) SetHUDScore(HUDScore);
|
if (bInitializeScore) SetHUDScore(HUDScore);
|
||||||
if (bInitializeDefeats) SetHUDDefeats(HUDDefeats);
|
if (bInitializeDefeats) SetHUDDefeats(HUDDefeats);
|
||||||
if (bInitializeCarriedAmmo) SetHUDCarriedAmmo(HUDCarriedAmmo);
|
if (bInitializeCarriedAmmo) SetHUDCarriedAmmo(HUDCarriedAmmo);
|
||||||
if (bInitializeHUDWeaponAmmo) SetHUDWeaponAmmo(HUDWeaponAmmo);
|
if (bInitializeWeaponAmmo) SetHUDWeaponAmmo(HUDWeaponAmmo);
|
||||||
|
|
||||||
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(GetPawn());
|
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(GetPawn());
|
||||||
if (BlasterCharacter && BlasterCharacter->GetCombat())
|
if (BlasterCharacter && BlasterCharacter->GetCombat())
|
||||||
{
|
{
|
||||||
|
@ -446,57 +477,13 @@ void ABlasterPlayerController::PollInit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::HighPingWarning()
|
void ABlasterPlayerController::SetupInputComponent()
|
||||||
{
|
{
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
Super::SetupInputComponent();
|
||||||
bool bHUDValid = BlasterHUD &&
|
if (InputComponent == nullptr) return;
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->HighPingImage &&
|
|
||||||
BlasterHUD->CharacterOverlay->HighPingAnimation;
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(1.f);
|
|
||||||
BlasterHUD->CharacterOverlay->PlayAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation, 0.f, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::StopHighPingWarning()
|
InputComponent->BindAction("Quit", IE_Pressed, this, &ABlasterPlayerController::ShowReturnToMainMenu);
|
||||||
{
|
|
||||||
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
|
|
||||||
bool bHUDValid = BlasterHUD &&
|
|
||||||
BlasterHUD->CharacterOverlay &&
|
|
||||||
BlasterHUD->CharacterOverlay->HighPingImage &&
|
|
||||||
BlasterHUD->CharacterOverlay->HighPingAnimation;
|
|
||||||
if (bHUDValid)
|
|
||||||
{
|
|
||||||
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(0.f);
|
|
||||||
if (BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation))
|
|
||||||
{
|
|
||||||
BlasterHUD->CharacterOverlay->StopAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ABlasterPlayerController::ShowReturnToMainMenu()
|
|
||||||
{
|
|
||||||
if (ReturnToMainMenuWidget == nullptr) return;
|
|
||||||
|
|
||||||
if (ReturnToMainMenu == nullptr)
|
|
||||||
{
|
|
||||||
ReturnToMainMenu = CreateWidget<UReturnToMainMenu>(this, ReturnToMainMenuWidget);
|
|
||||||
}
|
|
||||||
if (ReturnToMainMenu)
|
|
||||||
{
|
|
||||||
bReturnToMainMenuOpen = !bReturnToMainMenuOpen;
|
|
||||||
if (bReturnToMainMenuOpen)
|
|
||||||
{
|
|
||||||
ReturnToMainMenu->MenuSetup();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ReturnToMainMenu->MenuTearDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest)
|
void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest)
|
||||||
|
|
|
@ -143,7 +143,7 @@ private:
|
||||||
float bInitializeCarriedAmmo = false;
|
float bInitializeCarriedAmmo = false;
|
||||||
float HUDCarriedAmmo;
|
float HUDCarriedAmmo;
|
||||||
|
|
||||||
float bInitializeHUDWeaponAmmo = false;
|
float bInitializeWeaponAmmo = false;
|
||||||
float HUDWeaponAmmo;
|
float HUDWeaponAmmo;
|
||||||
|
|
||||||
// High Ping Indicator
|
// High Ping Indicator
|
||||||
|
|
|
@ -28,7 +28,7 @@ void AHitScanWeapon::Fire(const FVector& HitTarget)
|
||||||
WeaponTraceHit(Start, HitTarget, FireHit);
|
WeaponTraceHit(Start, HitTarget, FireHit);
|
||||||
|
|
||||||
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
|
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
|
||||||
if (BlasterCharacter && InstigatorController)
|
if (BlasterCharacter && InstigatorController)
|
||||||
{
|
{
|
||||||
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
|
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
|
||||||
if (HasAuthority() && bCauseAuthDamage)
|
if (HasAuthority() && bCauseAuthDamage)
|
||||||
|
|
|
@ -51,42 +51,6 @@ void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimi
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AProjectile::Tick(float DeltaTime)
|
|
||||||
{
|
|
||||||
Super::Tick(DeltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AProjectile::StartDestroyTimer()
|
|
||||||
{
|
|
||||||
GetWorldTimerManager().SetTimer(
|
|
||||||
DestroyTimer,
|
|
||||||
this,
|
|
||||||
&AProjectile::DestroyTimerFinished,
|
|
||||||
DestroyTime
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AProjectile::DestroyTimerFinished()
|
|
||||||
{
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AProjectile::Destroyed()
|
|
||||||
{
|
|
||||||
Super::Destroyed();
|
|
||||||
|
|
||||||
if (ImpactParticles)
|
|
||||||
{
|
|
||||||
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles, GetActorTransform());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImpactSound)
|
|
||||||
{
|
|
||||||
UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AProjectile::SpawnTrailSystem()
|
void AProjectile::SpawnTrailSystem()
|
||||||
{
|
{
|
||||||
if (TrailSystem)
|
if (TrailSystem)
|
||||||
|
@ -127,3 +91,37 @@ void AProjectile::ExplodeDamage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AProjectile::Tick(float DeltaTime)
|
||||||
|
{
|
||||||
|
Super::Tick(DeltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AProjectile::StartDestroyTimer()
|
||||||
|
{
|
||||||
|
GetWorldTimerManager().SetTimer(
|
||||||
|
DestroyTimer,
|
||||||
|
this,
|
||||||
|
&AProjectile::DestroyTimerFinished,
|
||||||
|
DestroyTime
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AProjectile::DestroyTimerFinished()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AProjectile::Destroyed()
|
||||||
|
{
|
||||||
|
Super::Destroyed();
|
||||||
|
|
||||||
|
if (ImpactParticles)
|
||||||
|
{
|
||||||
|
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles, GetActorTransform());
|
||||||
|
}
|
||||||
|
if (ImpactSound)
|
||||||
|
{
|
||||||
|
UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ void AProjectileBullet::BeginPlay()
|
||||||
PathParams.ActorsToIgnore.Add(this);
|
PathParams.ActorsToIgnore.Add(this);
|
||||||
|
|
||||||
FPredictProjectilePathResult PathResult;
|
FPredictProjectilePathResult PathResult;
|
||||||
|
|
||||||
UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult);
|
UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,30 +26,12 @@ void AProjectileGrenade::BeginPlay()
|
||||||
|
|
||||||
SpawnTrailSystem();
|
SpawnTrailSystem();
|
||||||
StartDestroyTimer();
|
StartDestroyTimer();
|
||||||
|
|
||||||
ProjectileMovementComponent->OnProjectileBounce.AddDynamic(this, &AProjectileGrenade::OnBounce);
|
ProjectileMovementComponent->OnProjectileBounce.AddDynamic(this, &AProjectileGrenade::OnBounce);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AProjectileGrenade::OnBounce(const FHitResult& ImpactResult, const FVector& ImpactVelocity)
|
void AProjectileGrenade::OnBounce(const FHitResult& ImpactResult, const FVector& ImpactVelocity)
|
||||||
{
|
{
|
||||||
if (ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(ImpactResult.GetActor()))
|
|
||||||
{
|
|
||||||
const APawn* FiringPawn = GetInstigator();
|
|
||||||
if (FiringPawn && HasAuthority())
|
|
||||||
{
|
|
||||||
AController* InstigatorController = FiringPawn->GetController();
|
|
||||||
if (InstigatorController)
|
|
||||||
{
|
|
||||||
UGameplayStatics::ApplyDamage(
|
|
||||||
BlasterCharacter,
|
|
||||||
Damage / 4,
|
|
||||||
InstigatorController,
|
|
||||||
this,
|
|
||||||
UDamageType::StaticClass()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BounceSound)
|
if (BounceSound)
|
||||||
{
|
{
|
||||||
UGameplayStatics::PlaySoundAtLocation(
|
UGameplayStatics::PlaySoundAtLocation(
|
||||||
|
|
|
@ -16,7 +16,7 @@ AProjectileRocket::AProjectileRocket()
|
||||||
ProjectileMesh->SetupAttachment(RootComponent);
|
ProjectileMesh->SetupAttachment(RootComponent);
|
||||||
ProjectileMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
ProjectileMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
|
|
||||||
RocketMovementComponent = CreateDefaultSubobject<URocketMovementComponent>("RocketMovementComponent");
|
RocketMovementComponent = CreateDefaultSubobject<URocketMovementComponent>(TEXT("RocketMovementComponent"));
|
||||||
RocketMovementComponent->bRotationFollowsVelocity = true;
|
RocketMovementComponent->bRotationFollowsVelocity = true;
|
||||||
RocketMovementComponent->SetIsReplicated(true);
|
RocketMovementComponent->SetIsReplicated(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,7 @@ void AProjectileWeapon::Fire(const FVector& HitTarget)
|
||||||
SpawnedProjectile = World->SpawnActor<AProjectile>(ServerSideRewindProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams);
|
SpawnedProjectile = World->SpawnActor<AProjectile>(ServerSideRewindProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams);
|
||||||
SpawnedProjectile->bUseServerSideRewind = true;
|
SpawnedProjectile->bUseServerSideRewind = true;
|
||||||
SpawnedProjectile->TraceStart = SocketTransform.GetLocation();
|
SpawnedProjectile->TraceStart = SocketTransform.GetLocation();
|
||||||
SpawnedProjectile->InitialVelocity= SpawnedProjectile->GetActorForwardVector() * SpawnedProjectile->InitialSpeed;
|
SpawnedProjectile->InitialVelocity = SpawnedProjectile->GetActorForwardVector() * SpawnedProjectile->InitialSpeed;
|
||||||
SpawnedProjectile->Damage = Damage;
|
|
||||||
}
|
}
|
||||||
else // Client, not locally controlled - spawn non-replicated projectile, no SSR
|
else // Client, not locally controlled - spawn non-replicated projectile, no SSR
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
|
|
||||||
#include "RocketMovementComponent.h"
|
#include "RocketMovementComponent.h"
|
||||||
|
|
||||||
UProjectileMovementComponent::EHandleBlockingHitResult URocketMovementComponent::HandleBlockingHit(const FHitResult& Hit, float TimeTick,
|
URocketMovementComponent::EHandleBlockingHitResult URocketMovementComponent::HandleBlockingHit(const FHitResult& Hit, float TimeTick,
|
||||||
const FVector& MoveDelta, float& SubTickTimeRemaining)
|
const FVector& MoveDelta, float& SubTickTimeRemaining)
|
||||||
{
|
{
|
||||||
Super::HandleBlockingHit(Hit, TimeTick, MoveDelta, SubTickTimeRemaining);
|
Super::HandleBlockingHit(Hit, TimeTick, MoveDelta, SubTickTimeRemaining);
|
||||||
|
|
||||||
return EHandleBlockingHitResult::AdvanceNextSubstep;
|
return EHandleBlockingHitResult::AdvanceNextSubstep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,6 @@ void AShotgun::ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVect
|
||||||
const FVector ToTargetNormalized = (HitTarget - TraceStart).GetSafeNormal();
|
const FVector ToTargetNormalized = (HitTarget - TraceStart).GetSafeNormal();
|
||||||
const FVector SphereCenter = TraceStart + ToTargetNormalized * DistanceToSphere;
|
const FVector SphereCenter = TraceStart + ToTargetNormalized * DistanceToSphere;
|
||||||
|
|
||||||
|
|
||||||
for (uint32 i = 0; i < NumberOfPellets; i++)
|
for (uint32 i = 0; i < NumberOfPellets; i++)
|
||||||
{
|
{
|
||||||
const FVector RandVec = UKismetMathLibrary::RandomUnitVector() * FMath::FRandRange(0.f, SphereRadius);
|
const FVector RandVec = UKismetMathLibrary::RandomUnitVector() * FMath::FRandRange(0.f, SphereRadius);
|
||||||
|
|
|
@ -95,25 +95,6 @@ void AWeapon::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AWeapon::OnRep_Owner()
|
|
||||||
{
|
|
||||||
Super::OnRep_Owner();
|
|
||||||
if (Owner == nullptr)
|
|
||||||
{
|
|
||||||
OwnerCharacter = nullptr;
|
|
||||||
OwnerController = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(Owner) : OwnerCharacter;
|
|
||||||
if (OwnerCharacter && OwnerCharacter->GetPrimaryWeapon() && OwnerCharacter->GetPrimaryWeapon() == this)
|
|
||||||
{
|
|
||||||
SetHUDAmmo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AWeapon::SetHUDAmmo()
|
void AWeapon::SetHUDAmmo()
|
||||||
{
|
{
|
||||||
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : OwnerCharacter;
|
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : OwnerCharacter;
|
||||||
|
@ -169,6 +150,24 @@ void AWeapon::ClientAddAmmo_Implementation(int32 AmmoToAdd)
|
||||||
SetHUDAmmo();
|
SetHUDAmmo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AWeapon::OnRep_Owner()
|
||||||
|
{
|
||||||
|
Super::OnRep_Owner();
|
||||||
|
if (Owner == nullptr)
|
||||||
|
{
|
||||||
|
OwnerCharacter = nullptr;
|
||||||
|
OwnerController = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(Owner) : OwnerCharacter;
|
||||||
|
if (OwnerCharacter && OwnerCharacter->GetPrimaryWeapon() && OwnerCharacter->GetPrimaryWeapon() == this)
|
||||||
|
{
|
||||||
|
SetHUDAmmo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AWeapon::SetWeaponState(EWeaponState State)
|
void AWeapon::SetWeaponState(EWeaponState State)
|
||||||
{
|
{
|
||||||
WeaponState = State;
|
WeaponState = State;
|
||||||
|
@ -204,7 +203,7 @@ void AWeapon::OnRep_WeaponState()
|
||||||
void AWeapon::OnEquipped()
|
void AWeapon::OnEquipped()
|
||||||
{
|
{
|
||||||
ShowPickupWidget(false);
|
ShowPickupWidget(false);
|
||||||
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
WeaponMesh->SetSimulatePhysics(false);
|
WeaponMesh->SetSimulatePhysics(false);
|
||||||
WeaponMesh->SetEnableGravity(false);
|
WeaponMesh->SetEnableGravity(false);
|
||||||
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
|
@ -227,10 +226,37 @@ void AWeapon::OnEquipped()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AWeapon::OnDropped()
|
||||||
|
{
|
||||||
|
if (HasAuthority())
|
||||||
|
{
|
||||||
|
AreaSphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
|
||||||
|
}
|
||||||
|
WeaponMesh->SetSimulatePhysics(true);
|
||||||
|
WeaponMesh->SetEnableGravity(true);
|
||||||
|
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
|
||||||
|
WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
|
||||||
|
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
|
||||||
|
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
|
||||||
|
WeaponMesh->SetCustomDepthStencilValue(CUSTOM_DEPTH_BLUE);
|
||||||
|
WeaponMesh->MarkRenderStateDirty();
|
||||||
|
EnableCustomDepth(true);
|
||||||
|
|
||||||
|
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : OwnerCharacter;
|
||||||
|
if (OwnerCharacter && bUseServerSideRewind)
|
||||||
|
{
|
||||||
|
OwnerController = OwnerController == nullptr ? Cast<ABlasterPlayerController>(OwnerCharacter->Controller) : OwnerController;
|
||||||
|
if (OwnerController && HasAuthority() && OwnerController->HighPingDelegate.IsBound())
|
||||||
|
{
|
||||||
|
OwnerController->HighPingDelegate.RemoveDynamic(this, &AWeapon::OnPingTooHigh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AWeapon::OnEquippedSecondary()
|
void AWeapon::OnEquippedSecondary()
|
||||||
{
|
{
|
||||||
ShowPickupWidget(false);
|
ShowPickupWidget(false);
|
||||||
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
WeaponMesh->SetSimulatePhysics(false);
|
WeaponMesh->SetSimulatePhysics(false);
|
||||||
WeaponMesh->SetEnableGravity(false);
|
WeaponMesh->SetEnableGravity(false);
|
||||||
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
|
@ -256,35 +282,6 @@ void AWeapon::OnEquippedSecondary()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AWeapon::OnDropped()
|
|
||||||
{
|
|
||||||
if (HasAuthority())
|
|
||||||
{
|
|
||||||
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
|
|
||||||
}
|
|
||||||
WeaponMesh->SetSimulatePhysics(true);
|
|
||||||
WeaponMesh->SetEnableGravity(true);
|
|
||||||
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
|
|
||||||
WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
|
|
||||||
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
|
|
||||||
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
|
|
||||||
WeaponMesh->SetCustomDepthStencilValue(CUSTOM_DEPTH_BLUE);
|
|
||||||
WeaponMesh->MarkRenderStateDirty();
|
|
||||||
EnableCustomDepth(true);
|
|
||||||
|
|
||||||
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : OwnerCharacter;
|
|
||||||
if (OwnerCharacter && bUseServerSideRewind)
|
|
||||||
{
|
|
||||||
OwnerController = OwnerController == nullptr ? Cast<ABlasterPlayerController>(OwnerCharacter->Controller) : OwnerController;
|
|
||||||
if (OwnerController && HasAuthority() && OwnerController->HighPingDelegate.IsBound())
|
|
||||||
{
|
|
||||||
OwnerController->HighPingDelegate.RemoveDynamic(this, &AWeapon::OnPingTooHigh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool AWeapon::IsEmpty()
|
bool AWeapon::IsEmpty()
|
||||||
{
|
{
|
||||||
return Ammo <= 0;
|
return Ammo <= 0;
|
||||||
|
|
Loading…
Reference in New Issue