Some bug fixes and reorg

This commit is contained in:
Kingsmedia 2022-05-29 11:59:15 +02:00
parent 4fa586e648
commit d2e581afe5
18 changed files with 477 additions and 523 deletions

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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);
}
}
}

View File

@ -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,

View File

@ -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]))

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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());
}
}

View File

@ -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);
*/ */
} }

View File

@ -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(

View File

@ -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);
} }

View File

@ -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
{ {

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;