From d2e581afe517f2ffd7f5d0ade9663359a874061a Mon Sep 17 00:00:00 2001 From: Kingsmedia Date: Sun, 29 May 2022 11:59:15 +0200 Subject: [PATCH] Some bug fixes and reorg --- Source/Blaster/Character/BlasterCharacter.cpp | 70 ++--- Source/Blaster/Components/CombatComponent.cpp | 281 +++++++++--------- Source/Blaster/Components/CombatComponent.h | 29 +- .../Components/LagCompensationComponent.cpp | 233 +++++++-------- .../Components/LagCompensationComponent.h | 4 +- Source/Blaster/GameMode/BlasterGameMode.cpp | 3 +- Source/Blaster/GameState/BlasterGameState.cpp | 2 +- .../BlasterPlayerController.cpp | 177 +++++------ .../BlasterPlayerController.h | 2 +- Source/Blaster/Weapon/HitScanWeapon.cpp | 2 +- Source/Blaster/Weapon/Projectile.cpp | 70 +++-- Source/Blaster/Weapon/ProjectileBullet.cpp | 1 + Source/Blaster/Weapon/ProjectileGrenade.cpp | 20 +- Source/Blaster/Weapon/ProjectileRocket.cpp | 2 +- Source/Blaster/Weapon/ProjectileWeapon.cpp | 3 +- .../Weapon/RocketMovementComponent.cpp | 3 +- Source/Blaster/Weapon/Shotgun.cpp | 1 - Source/Blaster/Weapon/Weapon.cpp | 97 +++--- 18 files changed, 477 insertions(+), 523 deletions(-) diff --git a/Source/Blaster/Character/BlasterCharacter.cpp b/Source/Blaster/Character/BlasterCharacter.cpp index b0b7ec4..4a0018d 100644 --- a/Source/Blaster/Character/BlasterCharacter.cpp +++ b/Source/Blaster/Character/BlasterCharacter.cpp @@ -49,11 +49,11 @@ ABlasterCharacter::ABlasterCharacter() Combat = CreateDefaultSubobject(TEXT("CombatComponent")); Combat->SetIsReplicated(true); - LagCompensation = CreateDefaultSubobject(TEXT("LagCompensation")); - Buff = CreateDefaultSubobject(TEXT("BuffComponent")); Buff->SetIsReplicated(true); - + + LagCompensation = CreateDefaultSubobject(TEXT("LagCompensation")); + GetCharacterMovement()->NavAgentProps.bCanCrouch = true; GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore); GetMesh()->SetCollisionObjectType(ECC_SkeletalMesh); @@ -112,15 +112,15 @@ ABlasterCharacter::ABlasterCharacter() hand_r = CreateDefaultSubobject(TEXT("hand_r")); hand_r->SetupAttachment(GetMesh(), FName("hand_r")); HitCollisionBoxes.Add(FName("hand_r"), hand_r); + + blanket = CreateDefaultSubobject(TEXT("blanket")); + blanket->SetupAttachment(GetMesh(), FName("backpack")); + HitCollisionBoxes.Add(FName("blanket"), blanket); backpack = CreateDefaultSubobject(TEXT("backpack")); backpack->SetupAttachment(GetMesh(), FName("backpack")); HitCollisionBoxes.Add(FName("backpack"), backpack); - blanket = CreateDefaultSubobject(TEXT("blanket")); - blanket->SetupAttachment(GetMesh(), FName("backpack")); - HitCollisionBoxes.Add(FName("blanket"), blanket); - thigh_l = CreateDefaultSubobject(TEXT("thigh_l")); thigh_l->SetupAttachment(GetMesh(), FName("thigh_l")); HitCollisionBoxes.Add(FName("thigh_l"), thigh_l); @@ -200,9 +200,9 @@ void ABlasterCharacter::MulticastEliminated_Implementation(bool bPlayerLeftGame) StartDissolve(); // Disable character movement + bDisableGameplay = true; GetCharacterMovement()->DisableMovement(); GetCharacterMovement()->StopMovementImmediately(); - bDisableGameplay = true; if (Combat) { Combat->FireButtonPressed(false); @@ -280,10 +280,9 @@ void ABlasterCharacter::Destroyed() ABlasterGameMode* BlasterGameMode = Cast(UGameplayStatics::GetGameMode(this)); bool bMatchNotInProgress = BlasterGameMode && BlasterGameMode->GetMatchState() != MatchState::InProgress; - - if (Combat && Combat->PrimaryWeapon && bMatchNotInProgress) + if (Combat && Combat->EquippedWeapon && bMatchNotInProgress) { - Combat->PrimaryWeapon->Destroy(); + Combat->EquippedWeapon->Destroy(); } } @@ -302,7 +301,6 @@ void ABlasterCharacter::MulticastGainedTheLead_Implementation() false ); } - if (CrownComponent) { CrownComponent->Activate(); @@ -320,7 +318,6 @@ void ABlasterCharacter::MulticastLostTheLead_Implementation() void ABlasterCharacter::BeginPlay() { Super::BeginPlay(); - SpawnDefaultWeapon(); UpdateHUDAmmo(); UpdateHUDHealth(); @@ -413,7 +410,7 @@ void ABlasterCharacter::PostInitializeComponents() void ABlasterCharacter::PlayFireMontage(bool bAiming) { - if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; + if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); if (AnimInstance && FireWeaponMontage) @@ -427,7 +424,7 @@ void ABlasterCharacter::PlayFireMontage(bool bAiming) void ABlasterCharacter::PlayReloadMontage() { - if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; + if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); if (AnimInstance && ReloadMontage) @@ -435,7 +432,7 @@ void ABlasterCharacter::PlayReloadMontage() AnimInstance->Montage_Play(ReloadMontage); FName SectionName; - switch (Combat->PrimaryWeapon->GetWeaponType()) + switch (Combat->EquippedWeapon->GetWeaponType()) { case EWeaponType::EWT_AssaultRifle: SectionName = FName("Rifle"); @@ -496,7 +493,7 @@ void ABlasterCharacter::PlaySwapMontage() void ABlasterCharacter::PlayHitReactMontage() { - if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; + if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); 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) { if (bEliminated) return; @@ -521,8 +526,8 @@ void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const } else { - DamageToHealth = FMath::Clamp(DamageToHealth - (Damage - Shield), 0.f, Damage); 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() { FVector Velocity = GetVelocity(); @@ -671,7 +668,7 @@ float ABlasterCharacter::CalculateSpeed() void ABlasterCharacter::AimOffset(float DeltaTime) { - if (Combat && Combat->PrimaryWeapon == nullptr) return; + if (Combat && Combat->EquippedWeapon == nullptr) return; float Speed = CalculateSpeed(); bool bIsInAir = GetCharacterMovement()->IsFalling(); @@ -714,7 +711,7 @@ void ABlasterCharacter::CalculateAO_Pitch() void ABlasterCharacter::SimProxiesTurn() { - if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; + if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; bRotateRootBone = false; float Speed = CalculateSpeed(); if (Speed > 0.f) @@ -806,9 +803,9 @@ void ABlasterCharacter::HideCameraIfCharacterClose() if ((FollowCamera->GetComponentLocation() - GetActorLocation()).Size() < CameraThreshold) { 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()) { @@ -818,9 +815,9 @@ void ABlasterCharacter::HideCameraIfCharacterClose() else { 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()) { @@ -868,10 +865,10 @@ void ABlasterCharacter::UpdateHUDShield() void ABlasterCharacter::UpdateHUDAmmo() { BlasterPlayerController = BlasterPlayerController == nullptr ? Cast(Controller) : BlasterPlayerController; - if (BlasterPlayerController && Combat && Combat->PrimaryWeapon) + if (BlasterPlayerController && Combat && Combat->EquippedWeapon) { 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) @@ -959,7 +955,7 @@ void ABlasterCharacter::OnRep_OverlappingWeapon(AWeapon* LastWeapon) bool ABlasterCharacter::IsWeaponEquipped() { - return Combat && Combat->PrimaryWeapon; + return Combat && Combat->EquippedWeapon; } bool ABlasterCharacter::IsAiming() @@ -970,7 +966,7 @@ bool ABlasterCharacter::IsAiming() AWeapon* ABlasterCharacter::GetPrimaryWeapon() { if (Combat == nullptr) return nullptr; - return Combat->PrimaryWeapon; + return Combat->EquippedWeapon; } FVector ABlasterCharacter::GetHitTarget() const diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index 5d0c0f5..ab83061 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -25,7 +25,7 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray& Out { Super::GetLifetimeReplicatedProps(OutLifetimeProps); - DOREPLIFETIME(UCombatComponent, PrimaryWeapon); + DOREPLIFETIME(UCombatComponent, EquippedWeapon); DOREPLIFETIME(UCombatComponent, SecondaryWeapon); DOREPLIFETIME(UCombatComponent, bAiming); DOREPLIFETIME_CONDITION(UCombatComponent, CarriedAmmo, COND_OwnerOnly); @@ -33,6 +33,14 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray& Out DOREPLIFETIME(UCombatComponent, Grenades); } +void UCombatComponent::ShotgunShellReload() +{ + if (Character && Character->HasAuthority()) + { + UpdateShotgunAmmoValues(); + } +} + void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount) { if (CarriedAmmoMap.Contains(WeaponType)) @@ -40,7 +48,7 @@ void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount) CarriedAmmoMap[WeaponType] = FMath::Clamp(CarriedAmmoMap[WeaponType] + AmmoAmount, 0, MaxCarriedAmmo); UpdateCarriedAmmo(); } - if (PrimaryWeapon && PrimaryWeapon->IsEmpty() && PrimaryWeapon->GetWeaponType() == WeaponType) + if (EquippedWeapon && EquippedWeapon->IsEmpty() && EquippedWeapon->GetWeaponType() == WeaponType) { Reload(); } @@ -84,29 +92,22 @@ void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActo void UCombatComponent::FireButtonPressed(bool bPressed) { bFireButtonPressed = bPressed; - if (bFireButtonPressed && PrimaryWeapon) + if (bFireButtonPressed) { Fire(); } } -void UCombatComponent::ShotgunShellReload() -{ - if (Character && Character->HasAuthority()) - { - UpdateShotgunAmmoValues(); - } -} - void UCombatComponent::Fire() { if (CanFire()) { bCanFire = false; - if (PrimaryWeapon) + if (EquippedWeapon) { CrosshairShootingFactor = .75f; - switch (PrimaryWeapon->FireType) + + switch (EquippedWeapon->FireType) { case EFireType::EFT_HitScan: FireHitScanWeapon(); @@ -125,52 +126,52 @@ void UCombatComponent::Fire() 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); - ServerFire(HitTarget, PrimaryWeapon->FireDelay); + ServerFire(HitTarget, EquippedWeapon->FireDelay); } } 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); - ServerFire(HitTarget, PrimaryWeapon->FireDelay); + ServerFire(HitTarget, EquippedWeapon->FireDelay); } } void UCombatComponent::FireShotgun() { - AShotgun* Shotgun = Cast(PrimaryWeapon); + AShotgun* Shotgun = Cast(EquippedWeapon); if (Shotgun && Character) { TArray HitTargets; Shotgun->ShotgunTraceEndWithScatter(HitTarget, HitTargets); if (!Character->HasAuthority()) ShotgunLocalFire(HitTargets); - ServerShotgunFire(HitTargets, PrimaryWeapon->FireDelay); + ServerShotgunFire(HitTargets, EquippedWeapon->FireDelay); } } void UCombatComponent::StartFireTimer() { - if (PrimaryWeapon == nullptr || Character == nullptr) return; + if (EquippedWeapon == nullptr || Character == nullptr) return; Character->GetWorldTimerManager().SetTimer( FireTimer, this, &UCombatComponent::FireTimerFinished, - PrimaryWeapon->FireDelay + EquippedWeapon->FireDelay ); } void UCombatComponent::FireTimerFinished() { - if (PrimaryWeapon == nullptr) return; + if (EquippedWeapon == nullptr) return; bCanFire = true; - if (bFireButtonPressed && PrimaryWeapon->bAutomatic) + if (bFireButtonPressed && EquippedWeapon->bAutomatic) { Fire(); } @@ -184,8 +185,8 @@ void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& Trac bool UCombatComponent::ServerFire_Validate(const FVector_NetQuantize& TraceHitTarget, float FireDelay) { - if (PrimaryWeapon == nullptr) return true; - return FMath::IsNearlyEqual(PrimaryWeapon->FireDelay, FireDelay, 0.001f); + if (EquippedWeapon == nullptr) return true; + return FMath::IsNearlyEqual(EquippedWeapon->FireDelay, FireDelay, 0.001f); } void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget) @@ -201,8 +202,8 @@ void UCombatComponent::ServerShotgunFire_Implementation(const TArray& TraceHitTargets, float FireDelay) { - if (PrimaryWeapon == nullptr) return true; - return FMath::IsNearlyEqual(PrimaryWeapon->FireDelay, FireDelay, 0.001f); + if (EquippedWeapon == nullptr) return true; + return FMath::IsNearlyEqual(EquippedWeapon->FireDelay, FireDelay, 0.001f); } void UCombatComponent::MulticastShotgunFire_Implementation(const TArray& TraceHitTargets) @@ -213,20 +214,21 @@ void UCombatComponent::MulticastShotgunFire_Implementation(const TArrayPlayFireMontage(bAiming); - PrimaryWeapon->Fire(TraceHitTarget); + EquippedWeapon->Fire(TraceHitTarget); } } void UCombatComponent::ShotgunLocalFire(const TArray& TraceHitTargets) { - AShotgun* Shotgun = Cast(PrimaryWeapon); + AShotgun* Shotgun = Cast(EquippedWeapon); if (Shotgun == nullptr || Character == nullptr) return; if (CombatState == ECombatState::ECS_Reloading || CombatState == ECombatState::ECS_Unoccupied) { + bLocallyReloading = false; Character->PlayFireMontage(bAiming); Shotgun->FireShotgun(TraceHitTargets); CombatState = ECombatState::ECS_Unoccupied; @@ -238,7 +240,7 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) if (Character == nullptr || WeaponToEquip == nullptr) return; if (CombatState != ECombatState::ECS_Unoccupied) return; - if (PrimaryWeapon != nullptr && SecondaryWeapon == nullptr) + if (EquippedWeapon != nullptr && SecondaryWeapon == nullptr) { EquipSecondaryWeapon(WeaponToEquip); } @@ -262,23 +264,17 @@ void UCombatComponent::SwapWeapons() if (SecondaryWeapon) SecondaryWeapon->EnableCustomDepth(false); } -bool UCombatComponent::ShouldSwapWeapons() -{ - return PrimaryWeapon != nullptr && SecondaryWeapon != nullptr; -} - void UCombatComponent::EquipPrimaryWeapon(AWeapon* WeaponToEquip) { if (WeaponToEquip == nullptr) return; - - DropPrimaryWeapon(); - PrimaryWeapon = WeaponToEquip; - PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToRightHand(PrimaryWeapon); - PrimaryWeapon->SetOwner(Character); - PrimaryWeapon->SetHUDAmmo(); + DropEquippedWeapon(); + EquippedWeapon = WeaponToEquip; + EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToRightHand(EquippedWeapon); + EquippedWeapon->SetOwner(Character); + EquippedWeapon->SetHUDAmmo(); UpdateCarriedAmmo(); - PlayEquipWeaponSound(PrimaryWeapon); + PlayEquipWeaponSound(WeaponToEquip); ReloadEmptyWeapon(); } @@ -288,44 +284,29 @@ void UCombatComponent::EquipSecondaryWeapon(AWeapon* WeaponToEquip) SecondaryWeapon = WeaponToEquip; SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); AttachActorToBackpack(WeaponToEquip); - PlayEquipWeaponSound(SecondaryWeapon); + PlayEquipWeaponSound(WeaponToEquip); SecondaryWeapon->SetOwner(Character); } -void UCombatComponent::OnRep_PrimaryWeapon() +void UCombatComponent::OnRep_Aiming() { - if (PrimaryWeapon && Character) + if (Character && Character->IsLocallyControlled()) { - PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToRightHand(PrimaryWeapon); - Character->GetCharacterMovement()->bOrientRotationToMovement = false; - Character->bUseControllerRotationYaw = true; - PlayEquipWeaponSound(PrimaryWeapon); - PrimaryWeapon->SetHUDAmmo(); + bAiming = bAimButtonPressed; } } -void UCombatComponent::OnRep_SecondaryWeapon() +void UCombatComponent::DropEquippedWeapon() { - if (SecondaryWeapon && Character) + if (EquippedWeapon) { - SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); - AttachActorToBackpack(SecondaryWeapon); - PlayEquipWeaponSound(SecondaryWeapon); - } -} - -void UCombatComponent::DropPrimaryWeapon() -{ - if (PrimaryWeapon) - { - PrimaryWeapon->Dropped(); + EquippedWeapon->Dropped(); } } 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")); if (HandSocket) { @@ -335,8 +316,8 @@ void UCombatComponent::AttachActorToRightHand(AActor* ActorToAttach) void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach) { - if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || PrimaryWeapon == nullptr) return; - bool bUsePistolSocket = PrimaryWeapon->IsPistol() || PrimaryWeapon->IsSMG(); + if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || EquippedWeapon == nullptr) return; + bool bUsePistolSocket = EquippedWeapon->IsPistol() || EquippedWeapon->IsSMG(); FName SocketName = bUsePistolSocket ? FName("LeftHandPistolSocket") : FName("LeftHandSocket"); const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(SocketName); if (HandSocket) @@ -347,7 +328,7 @@ void UCombatComponent::AttachActorToLeftHand(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")); if (BackpackSocket) { @@ -357,10 +338,10 @@ void UCombatComponent::AttachActorToBackpack(AActor* ActorToAttach) void UCombatComponent::UpdateCarriedAmmo() { - if (PrimaryWeapon == nullptr) return; - if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType())) + if (EquippedWeapon == nullptr) return; + if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) { - CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()]; + CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; } Controller = Controller == nullptr ? Cast(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( this, - Weapon->EquipSound, + WeaponToEquip->EquipSound, Character->GetActorLocation() ); } @@ -384,7 +365,7 @@ void UCombatComponent::PlayEquipWeaponSound(const AWeapon* Weapon) void UCombatComponent::ReloadEmptyWeapon() { - if (PrimaryWeapon && PrimaryWeapon->IsEmpty()) + if (EquippedWeapon && EquippedWeapon->IsEmpty()) { Reload(); } @@ -392,7 +373,7 @@ void UCombatComponent::ReloadEmptyWeapon() 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(); HandleReload(); @@ -402,10 +383,10 @@ void UCombatComponent::Reload() void UCombatComponent::ServerReload_Implementation() { - if (Character == nullptr || PrimaryWeapon == nullptr) return; + if (Character == nullptr || EquippedWeapon == nullptr) return; // return if weapon mag is at max capacity - if (PrimaryWeapon->GetAmmo() == PrimaryWeapon->GetMagCapacity()) return; + if (EquippedWeapon->GetAmmo() == EquippedWeapon->GetMagCapacity()) return; CombatState = ECombatState::ECS_Reloading; if (!Character->IsLocallyControlled()) HandleReload(); @@ -438,15 +419,17 @@ void UCombatComponent::FinishedSwap() void UCombatComponent::FinishedSwapAttachWeapons() { - AWeapon* TempWeapon = PrimaryWeapon; - PrimaryWeapon = SecondaryWeapon; + PlayEquipWeaponSound(SecondaryWeapon); + + if (Character == nullptr || !Character->HasAuthority()) return; + AWeapon* TempWeapon = EquippedWeapon; + EquippedWeapon = SecondaryWeapon; SecondaryWeapon = TempWeapon; - PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToRightHand(PrimaryWeapon); - PrimaryWeapon->SetHUDAmmo(); + EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToRightHand(EquippedWeapon); + EquippedWeapon->SetHUDAmmo(); UpdateCarriedAmmo(); - PlayEquipWeaponSound(PrimaryWeapon); SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); AttachActorToBackpack(SecondaryWeapon); @@ -454,49 +437,54 @@ void UCombatComponent::FinishedSwapAttachWeapons() void UCombatComponent::DropWeapons() { - if (PrimaryWeapon) PrimaryWeapon->Dropped(); + if (EquippedWeapon) EquippedWeapon->Dropped(); if (SecondaryWeapon) SecondaryWeapon->Dropped(); } void UCombatComponent::UpdateAmmoValues() { - if (Character == nullptr || PrimaryWeapon == nullptr) return; + if (Character == nullptr || EquippedWeapon == nullptr) return; int32 ReloadAmount = AmountToReload(); - if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType())) + if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) { - CarriedAmmoMap[PrimaryWeapon->GetWeaponType()] -= ReloadAmount; - CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()]; + CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= ReloadAmount; + CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; } Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; if (Controller) { Controller->SetHUDCarriedAmmo(CarriedAmmo); } - PrimaryWeapon->AddAmmo(ReloadAmount); + EquippedWeapon->AddAmmo(ReloadAmount); } 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; - CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()]; + CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= 1; + CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; } Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; if (Controller) { Controller->SetHUDCarriedAmmo(CarriedAmmo); } - PrimaryWeapon->AddAmmo(1); + EquippedWeapon->AddAmmo(1); bCanFire = true; - if (PrimaryWeapon->IsFull() || CarriedAmmo == 0) + if (EquippedWeapon->IsFull() || CarriedAmmo == 0) { JumpToShotgunEnd(); } } +void UCombatComponent::OnRep_Grenades() +{ + UpdateHUDGrenades(); +} + void UCombatComponent::JumpToShotgunEnd() { // Jump to ShotgunEnd section @@ -510,7 +498,7 @@ void UCombatComponent::JumpToShotgunEnd() void UCombatComponent::ThrowGrenadeFinished() { CombatState = ECombatState::ECS_Unoccupied; - AttachActorToRightHand(PrimaryWeapon); + AttachActorToRightHand(EquippedWeapon); } void UCombatComponent::LaunchGrenade() @@ -531,7 +519,6 @@ void UCombatComponent::ServerLaunchGrenade_Implementation(const FVector_NetQuant FActorSpawnParameters SpawnParams; SpawnParams.Owner = Character; SpawnParams.Instigator = Character; - UWorld* World = GetWorld(); if (World) { @@ -562,7 +549,7 @@ void UCombatComponent::OnRep_CombatState() if (Character && !Character->IsLocallyControlled()) { Character->PlayThrowGrenadeMontage(); - AttachActorToLeftHand(PrimaryWeapon); + AttachActorToLeftHand(EquippedWeapon); ShowAttachedGrenade(true); } break; @@ -585,12 +572,12 @@ void UCombatComponent::HandleReload() int32 UCombatComponent::AmountToReload() { - if (PrimaryWeapon == nullptr) return 0; - int32 RoomInMag = PrimaryWeapon->GetMagCapacity() - PrimaryWeapon->GetAmmo(); + if (EquippedWeapon == nullptr) return 0; + 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); return FMath::Clamp(RoomInMag, 0, Least); } @@ -600,12 +587,12 @@ int32 UCombatComponent::AmountToReload() void UCombatComponent::ThrowGrenade() { if (Grenades == 0) return; - if (CombatState != ECombatState::ECS_Unoccupied || PrimaryWeapon == nullptr) return; + if (CombatState != ECombatState::ECS_Unoccupied || EquippedWeapon == nullptr) return; CombatState = ECombatState::ECS_ThrowingGrenade; if (Character) { Character->PlayThrowGrenadeMontage(); - AttachActorToLeftHand(PrimaryWeapon); + AttachActorToLeftHand(EquippedWeapon); ShowAttachedGrenade(true); } if (Character && !Character->HasAuthority()) @@ -626,27 +613,27 @@ void UCombatComponent::ServerThrowGrenade_Implementation() if (Character) { Character->PlayThrowGrenadeMontage(); - AttachActorToLeftHand(PrimaryWeapon); + AttachActorToLeftHand(EquippedWeapon); ShowAttachedGrenade(true); } Grenades = FMath::Clamp(Grenades -1, 0, MaxGrenades); UpdateHUDGrenades(); } -void UCombatComponent::OnRep_Grenades() -{ - UpdateHUDGrenades(); -} - void UCombatComponent::UpdateHUDGrenades() { - Controller = Controller == nullptr ? Cast(Character->Controller) : Controller;Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; + Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; if (Controller) { Controller->SetHUDGrenades(Grenades); } } +bool UCombatComponent::ShouldSwapWeapons() +{ + return EquippedWeapon != nullptr && SecondaryWeapon != nullptr; +} + void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade) { 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) { FVector2D ViewportSize; @@ -714,13 +725,13 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime) HUD = HUD == nullptr ? Cast(Controller->GetHUD()) : HUD; if (HUD) { - if (PrimaryWeapon) + if (EquippedWeapon) { - HUDPackage.CrosshairsCenter = PrimaryWeapon->CrosshairsCenter; - HUDPackage.CrosshairsLeft = PrimaryWeapon->CrosshairsLeft; - HUDPackage.CrosshairsRight = PrimaryWeapon->CrosshairsRight; - HUDPackage.CrosshairsBottom = PrimaryWeapon->CrosshairsBottom; - HUDPackage.CrosshairsTop = PrimaryWeapon->CrosshairsTop; + HUDPackage.CrosshairsCenter = EquippedWeapon->CrosshairsCenter; + HUDPackage.CrosshairsLeft = EquippedWeapon->CrosshairsLeft; + HUDPackage.CrosshairsRight = EquippedWeapon->CrosshairsRight; + HUDPackage.CrosshairsBottom = EquippedWeapon->CrosshairsBottom; + HUDPackage.CrosshairsTop = EquippedWeapon->CrosshairsTop; } else { @@ -774,11 +785,11 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime) void UCombatComponent::InterpFOV(float DeltaTime) { - if (PrimaryWeapon == nullptr) return; + if (EquippedWeapon == nullptr) return; if (bAiming) { - CurrentFOV = FMath::FInterpTo(CurrentFOV, PrimaryWeapon->GetZoomedFOV(), DeltaTime, PrimaryWeapon->GetZoomInterpSpeed()); + CurrentFOV = FMath::FInterpTo(CurrentFOV, EquippedWeapon->GetZoomedFOV(), DeltaTime, EquippedWeapon->GetZoomInterpSpeed()); } else { @@ -792,14 +803,14 @@ void UCombatComponent::InterpFOV(float DeltaTime) void UCombatComponent::SetAiming(bool bIsAiming) { - if (Character == nullptr || PrimaryWeapon == nullptr) return; + if (Character == nullptr || EquippedWeapon == nullptr) return; bAiming = bIsAiming; ServerSetAiming(bIsAiming); if (Character) { Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed; } - if (Character->IsLocallyControlled() && PrimaryWeapon->IsSniper()) + if (Character->IsLocallyControlled() && EquippedWeapon->IsSniper()) { 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() { - if (PrimaryWeapon == nullptr) return false; - if (PrimaryWeapon->IsEmpty()) return false; + if (EquippedWeapon == nullptr) return false; + if (EquippedWeapon->IsEmpty()) 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; return CombatState == ECombatState::ECS_Unoccupied; } @@ -843,8 +846,8 @@ void UCombatComponent::OnRep_CarriedAmmo() Controller->SetHUDCarriedAmmo(CarriedAmmo); } bool bJumpToShotgunEnd = CombatState == ECombatState::ECS_Reloading && - PrimaryWeapon != nullptr && - PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun && + EquippedWeapon != nullptr && + EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun && CarriedAmmo == 0; if (bJumpToShotgunEnd) diff --git a/Source/Blaster/Components/CombatComponent.h b/Source/Blaster/Components/CombatComponent.h index cc89f42..a261ec7 100644 --- a/Source/Blaster/Components/CombatComponent.h +++ b/Source/Blaster/Components/CombatComponent.h @@ -62,15 +62,18 @@ protected: void ServerSetAiming(bool bIsAiming); UFUNCTION() - void OnRep_PrimaryWeapon(); + void OnRep_EquippedWeapon(); + UFUNCTION() void OnRep_SecondaryWeapon(); - + void Fire(); void FireProjectileWeapon(); void FireHitScanWeapon(); void FireShotgun(); - + void LocalFire(const FVector_NetQuantize& TraceHitTarget); + void ShotgunLocalFire(const TArray& TraceHitTargets); + UFUNCTION(Server, Reliable, WithValidation) void ServerFire(const FVector_NetQuantize& TraceHitTarget, float FireDelay); @@ -101,12 +104,12 @@ protected: UPROPERTY(EditAnywhere) TSubclassOf GrenadeClass; - void DropPrimaryWeapon(); + void DropEquippedWeapon(); void AttachActorToRightHand(AActor* ActorToAttach); void AttachActorToLeftHand(AActor* ActorToAttach); void AttachActorToBackpack(AActor* ActorToAttach); void UpdateCarriedAmmo(); - void PlayEquipWeaponSound(const AWeapon* Weapon); + void PlayEquipWeaponSound(const AWeapon* WeaponToEquip); void ReloadEmptyWeapon(); void ShowAttachedGrenade(bool bShowGrenade); void EquipPrimaryWeapon(AWeapon* WeaponToEquip); @@ -121,10 +124,10 @@ private: UPROPERTY() ABlasterHUD* HUD; - UPROPERTY(ReplicatedUsing=OnRep_PrimaryWeapon) - AWeapon* PrimaryWeapon; + UPROPERTY(ReplicatedUsing = OnRep_EquippedWeapon) + AWeapon* EquippedWeapon; - UPROPERTY(ReplicatedUsing=OnRep_SecondaryWeapon) + UPROPERTY(ReplicatedUsing = OnRep_SecondaryWeapon) AWeapon* SecondaryWeapon; UPROPERTY(ReplicatedUsing = OnRep_Aiming) @@ -148,6 +151,9 @@ private: float CrosshairInAirFactor; float CrosshairAimFactor; float CrosshairShootingFactor; + + FVector HitTarget; + FHUDPackage HUDPackage; // Aiming and FOV @@ -164,8 +170,7 @@ private: float ZoomInterpSpeed = 20.f; void InterpFOV(float DeltaTime); - - FVector HitTarget; + // Automatic fire FTimerHandle FireTimer; @@ -173,13 +178,11 @@ private: void StartFireTimer(); void FireTimerFinished(); - void LocalFire(const FVector_NetQuantize& TraceHitTarget); - void ShotgunLocalFire(const TArray& TraceHitTargets); bool CanFire(); // Carried ammo for the currently equipped weapon - UPROPERTY(ReplicatedUsing=OnRep_CarriedAmmo) + UPROPERTY(ReplicatedUsing = OnRep_CarriedAmmo) int32 CarriedAmmo; UFUNCTION() diff --git a/Source/Blaster/Components/LagCompensationComponent.cpp b/Source/Blaster/Components/LagCompensationComponent.cpp index 0d1f08e..189de11 100644 --- a/Source/Blaster/Components/LagCompensationComponent.cpp +++ b/Source/Blaster/Components/LagCompensationComponent.cpp @@ -13,110 +13,6 @@ ULagCompensationComponent::ULagCompensationComponent() 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& HitCharacters, const FVector_NetQuantize& TraceStart, - const TArray& 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(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) { const float Distance = YoungerFrame.Time - OlderFrame.Time; @@ -134,7 +30,7 @@ FFramePackage ULagCompensationComponent::InterpBetweenFrames(const FFramePackage FBoxInformation InterpBoxInfo; InterpBoxInfo.Location = FMath::VInterpTo(OlderBox.Location, YoungerBox.Location, 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); } @@ -167,7 +63,6 @@ FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackag TraceEnd, ECC_HitBox ); - if (ConfirmHitResult.bBlockingHit) // we hit the head, return early { ResetHitBoxes(HitCharacter, CurrentFrame); @@ -322,7 +217,7 @@ FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(cons } // Enable collision for all boxes, then disable for head box - for (auto& Frame :FramePackages) + for (auto& Frame : FramePackages) { for (auto& HitBoxPair : Frame.Character->HitCollisionBoxes) { @@ -377,7 +272,6 @@ FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(cons void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage) { if (HitCharacter == nullptr) return; - for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes) { if (HitBoxPair.Value != nullptr) @@ -385,8 +279,7 @@ void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacte FBoxInformation BoxInfo; BoxInfo.Location = HitBoxPair.Value->GetComponentLocation(); BoxInfo.Rotation = HitBoxPair.Value->GetComponentRotation(); - BoxInfo.BoxExtend = HitBoxPair.Value->GetScaledBoxExtent(); - + BoxInfo.BoxExtent = HitBoxPair.Value->GetScaledBoxExtent(); OutFramePackage.HitBoxInfo.Add(HitBoxPair.Key, BoxInfo); } } @@ -395,14 +288,13 @@ void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacte void ULagCompensationComponent::MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package) { if (HitCharacter == nullptr) return; - for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes) { if (HitBoxPair.Value != nullptr) { HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location); 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) { if (HitCharacter == nullptr) return; - for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes) { if (HitBoxPair.Value != nullptr) { HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location); 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); } } @@ -430,7 +321,7 @@ void ULagCompensationComponent::ShowFramePackage(const FFramePackage& Package, c DrawDebugBox( GetWorld(), BoxInfo.Value.Location, - BoxInfo.Value.BoxExtend, + BoxInfo.Value.BoxExtent, FQuat(BoxInfo.Value.Rotation), Color, false, @@ -446,7 +337,7 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar 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 FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime); @@ -471,9 +362,7 @@ FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitC HitCharacter->GetLagCompensation() == nullptr || HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr || HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr; - if (bReturn) FFramePackage(); - // Frame package that we check to verify a hit FFramePackage FrameToCheck; bool bShouldInterpolate = true; @@ -512,17 +401,76 @@ FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitC FrameToCheck = Older->GetValue(); bShouldInterpolate = false; } - if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr? { - // Interpolate between Younger and Older - FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime); + // Interpolate between Younger and Older + FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime); } - FrameToCheck.Character = HitCharacter; 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& HitCharacters, const FVector_NetQuantize& TraceStart, + const TArray& 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) { @@ -538,3 +486,44 @@ void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickTy 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(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); + } + } +} diff --git a/Source/Blaster/Components/LagCompensationComponent.h b/Source/Blaster/Components/LagCompensationComponent.h index 908d07d..4760a5a 100644 --- a/Source/Blaster/Components/LagCompensationComponent.h +++ b/Source/Blaster/Components/LagCompensationComponent.h @@ -19,7 +19,7 @@ struct FBoxInformation FRotator Rotation; UPROPERTY() - FVector BoxExtend; + FVector BoxExtent; }; USTRUCT(BlueprintType) @@ -81,7 +81,7 @@ public: ); // Projectiles - FServerSideRewindResult ProjectilServerSideRewind( + FServerSideRewindResult ProjectileServerSideRewind( ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize100& InitialVelocity, diff --git a/Source/Blaster/GameMode/BlasterGameMode.cpp b/Source/Blaster/GameMode/BlasterGameMode.cpp index 0c045da..f8af36b 100644 --- a/Source/Blaster/GameMode/BlasterGameMode.cpp +++ b/Source/Blaster/GameMode/BlasterGameMode.cpp @@ -88,9 +88,9 @@ void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedChara { PlayersCurrentlyInTheLead.Add(LeadPlayer); } + AttackerPlayerState->IncreaseScore(1.f); BlasterGameState->UpdateTopScore(AttackerPlayerState); - if (BlasterGameState->TopScoringPlayers.Contains(AttackerPlayerState)) { ABlasterCharacter* Leader = Cast(AttackerPlayerState->GetPawn()); @@ -99,6 +99,7 @@ void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedChara Leader->MulticastGainedTheLead(); } } + for (int32 i = 0; i < PlayersCurrentlyInTheLead.Num(); i++) { if (!BlasterGameState->TopScoringPlayers.Contains(PlayersCurrentlyInTheLead[i])) diff --git a/Source/Blaster/GameState/BlasterGameState.cpp b/Source/Blaster/GameState/BlasterGameState.cpp index 8fa3ce8..9c676b7 100644 --- a/Source/Blaster/GameState/BlasterGameState.cpp +++ b/Source/Blaster/GameState/BlasterGameState.cpp @@ -24,7 +24,7 @@ void ABlasterGameState::UpdateTopScore(ABlasterPlayerState* ScoringPlayer) { TopScoringPlayers.AddUnique(ScoringPlayer); } - else if (ScoringPlayer->GetScore() < TopScore) + else if (ScoringPlayer->GetScore() > TopScore) { TopScoringPlayers.Empty(); TopScoringPlayers.AddUnique(ScoringPlayer); diff --git a/Source/Blaster/PlayerController/BlasterPlayerController.cpp b/Source/Blaster/PlayerController/BlasterPlayerController.cpp index de0bf5c..fe38fa7 100644 --- a/Source/Blaster/PlayerController/BlasterPlayerController.cpp +++ b/Source/Blaster/PlayerController/BlasterPlayerController.cpp @@ -28,15 +28,6 @@ void ABlasterPlayerController::BeginPlay() ServerCheckMatchState(); } -void ABlasterPlayerController::SetupInputComponent() -{ - Super::SetupInputComponent(); - - if (InputComponent == nullptr) return; - - InputComponent->BindAction("Quit", IE_Pressed, this, &ABlasterPlayerController::ShowReturnToMainMenu); -} - void ABlasterPlayerController::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); @@ -72,11 +63,10 @@ void ABlasterPlayerController::Tick(float DeltaTime) void ABlasterPlayerController::CheckPing(float DeltaTime) { + if (HasAuthority()) return; HighPingRunningTime += DeltaTime; if (HighPingRunningTime > CheckPingFrequency) { - HighPingRunningTime = 0.f; - PlayerState = PlayerState == nullptr ? GetPlayerState() : PlayerState; if (PlayerState) { @@ -85,19 +75,18 @@ void ABlasterPlayerController::CheckPing(float DeltaTime) HighPingWarning(); PingAnimationRunningTime = 0.f; ServerReportPingStatus(true); - } else + } + else { ServerReportPingStatus(false); } } + HighPingRunningTime = 0.f; } - bool bHighPingAnimationPlaying = - BlasterHUD && - BlasterHUD->CharacterOverlay && + BlasterHUD && BlasterHUD->CharacterOverlay && BlasterHUD->CharacterOverlay->HighPingAnimation && BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation); - if (bHighPingAnimationPlaying) { PingAnimationRunningTime += DeltaTime; @@ -108,6 +97,27 @@ void ABlasterPlayerController::CheckPing(float DeltaTime) } } +void ABlasterPlayerController::ShowReturnToMainMenu() +{ + if (ReturnToMainMenuWidget == nullptr) return; + if (ReturnToMainMenu == nullptr) + { + ReturnToMainMenu = CreateWidget(this, ReturnToMainMenuWidget); + } + if (ReturnToMainMenu) + { + bReturnToMainMenuOpen = !bReturnToMainMenuOpen; + if (bReturnToMainMenuOpen) + { + ReturnToMainMenu->MenuSetup(); + } + else + { + ReturnToMainMenu->MenuTearDown(); + } + } +} + // Is the ping to high? void ABlasterPlayerController::ServerReportPingStatus_Implementation(bool bHighPing) { @@ -160,6 +170,37 @@ void ABlasterPlayerController::CheckTimeSync(float DeltaTime) } } +void ABlasterPlayerController::HighPingWarning() +{ + BlasterHUD = BlasterHUD == nullptr ? Cast(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(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() { ABlasterGameMode* GameMode = Cast(UGameplayStatics::GetGameMode(this)); @@ -292,7 +333,7 @@ void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo) } else { - bInitializeHUDWeaponAmmo = true; + bInitializeWeaponAmmo = true; HUDWeaponAmmo = Ammo; } } @@ -315,24 +356,6 @@ void ABlasterPlayerController::SetHUDCarriedAmmo(int32 Ammo) } } -void ABlasterPlayerController::SetHUDGrenades(int32 Grenades) -{ - BlasterHUD = BlasterHUD == nullptr ? Cast(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) { BlasterHUD = BlasterHUD == nullptr ? Cast(GetHUD()) : BlasterHUD; @@ -377,24 +400,31 @@ void ABlasterPlayerController::SetHUDAnnouncementCountdown(float CountdownTime) } } +void ABlasterPlayerController::SetHUDGrenades(int32 Grenades) +{ + BlasterHUD = BlasterHUD == nullptr ? Cast(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() { float TimeLeft = 0.f; if (MatchState == MatchState::WaitingToStart) TimeLeft = WarmupTime - GetServerTime(); // + LevelStartingTime; else if (MatchState == MatchState::InProgress) TimeLeft = WarmupTime + MatchTime - GetServerTime(); // + LevelStartingTime; else if (MatchState == MatchState::Cooldown) TimeLeft = WarmupTime + MatchTime + CooldownTime - GetServerTime(); // + LevelStartingTime; - uint32 SecondsLeft = FMath::CeilToInt(TimeLeft); - - if (HasAuthority()) - { - BlasterGameMode = BlasterGameMode == nullptr ? Cast(UGameplayStatics::GetGameMode(this)) : BlasterGameMode; - if (BlasterGameMode) - { - SecondsLeft = FMath::CeilToInt(BlasterGameMode->GetCountdownTime()); - } - } - if (CountdownInt != SecondsLeft) { if (MatchState == MatchState::WaitingToStart || MatchState == MatchState::Cooldown) @@ -435,7 +465,8 @@ void ABlasterPlayerController::PollInit() if (bInitializeScore) SetHUDScore(HUDScore); if (bInitializeDefeats) SetHUDDefeats(HUDDefeats); if (bInitializeCarriedAmmo) SetHUDCarriedAmmo(HUDCarriedAmmo); - if (bInitializeHUDWeaponAmmo) SetHUDWeaponAmmo(HUDWeaponAmmo); + if (bInitializeWeaponAmmo) SetHUDWeaponAmmo(HUDWeaponAmmo); + ABlasterCharacter* BlasterCharacter = Cast(GetPawn()); if (BlasterCharacter && BlasterCharacter->GetCombat()) { @@ -446,57 +477,13 @@ void ABlasterPlayerController::PollInit() } } -void ABlasterPlayerController::HighPingWarning() +void ABlasterPlayerController::SetupInputComponent() { - BlasterHUD = BlasterHUD == nullptr ? Cast(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); - } -} + Super::SetupInputComponent(); + if (InputComponent == nullptr) return; -void ABlasterPlayerController::StopHighPingWarning() -{ - BlasterHUD = BlasterHUD == nullptr ? Cast(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); - } - } -} + InputComponent->BindAction("Quit", IE_Pressed, this, &ABlasterPlayerController::ShowReturnToMainMenu); -void ABlasterPlayerController::ShowReturnToMainMenu() -{ - if (ReturnToMainMenuWidget == nullptr) return; - - if (ReturnToMainMenu == nullptr) - { - ReturnToMainMenu = CreateWidget(this, ReturnToMainMenuWidget); - } - if (ReturnToMainMenu) - { - bReturnToMainMenuOpen = !bReturnToMainMenuOpen; - if (bReturnToMainMenuOpen) - { - ReturnToMainMenu->MenuSetup(); - } - else - { - ReturnToMainMenu->MenuTearDown(); - } - } } void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest) diff --git a/Source/Blaster/PlayerController/BlasterPlayerController.h b/Source/Blaster/PlayerController/BlasterPlayerController.h index 8aceb84..940fa4f 100644 --- a/Source/Blaster/PlayerController/BlasterPlayerController.h +++ b/Source/Blaster/PlayerController/BlasterPlayerController.h @@ -143,7 +143,7 @@ private: float bInitializeCarriedAmmo = false; float HUDCarriedAmmo; - float bInitializeHUDWeaponAmmo = false; + float bInitializeWeaponAmmo = false; float HUDWeaponAmmo; // High Ping Indicator diff --git a/Source/Blaster/Weapon/HitScanWeapon.cpp b/Source/Blaster/Weapon/HitScanWeapon.cpp index a76c95f..45706fb 100644 --- a/Source/Blaster/Weapon/HitScanWeapon.cpp +++ b/Source/Blaster/Weapon/HitScanWeapon.cpp @@ -28,7 +28,7 @@ void AHitScanWeapon::Fire(const FVector& HitTarget) WeaponTraceHit(Start, HitTarget, FireHit); ABlasterCharacter* BlasterCharacter = Cast(FireHit.GetActor()); - if (BlasterCharacter && InstigatorController) + if (BlasterCharacter && InstigatorController) { bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled(); if (HasAuthority() && bCauseAuthDamage) diff --git a/Source/Blaster/Weapon/Projectile.cpp b/Source/Blaster/Weapon/Projectile.cpp index 6fa72a1..e4d5f78 100644 --- a/Source/Blaster/Weapon/Projectile.cpp +++ b/Source/Blaster/Weapon/Projectile.cpp @@ -51,42 +51,6 @@ void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimi 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() { 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()); + } +} diff --git a/Source/Blaster/Weapon/ProjectileBullet.cpp b/Source/Blaster/Weapon/ProjectileBullet.cpp index a2ef34f..a83e549 100644 --- a/Source/Blaster/Weapon/ProjectileBullet.cpp +++ b/Source/Blaster/Weapon/ProjectileBullet.cpp @@ -86,6 +86,7 @@ void AProjectileBullet::BeginPlay() PathParams.ActorsToIgnore.Add(this); FPredictProjectilePathResult PathResult; + UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult); */ } diff --git a/Source/Blaster/Weapon/ProjectileGrenade.cpp b/Source/Blaster/Weapon/ProjectileGrenade.cpp index c5d4c38..bd3b322 100644 --- a/Source/Blaster/Weapon/ProjectileGrenade.cpp +++ b/Source/Blaster/Weapon/ProjectileGrenade.cpp @@ -26,30 +26,12 @@ void AProjectileGrenade::BeginPlay() SpawnTrailSystem(); StartDestroyTimer(); + ProjectileMovementComponent->OnProjectileBounce.AddDynamic(this, &AProjectileGrenade::OnBounce); } void AProjectileGrenade::OnBounce(const FHitResult& ImpactResult, const FVector& ImpactVelocity) { - if (ABlasterCharacter* BlasterCharacter = Cast(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) { UGameplayStatics::PlaySoundAtLocation( diff --git a/Source/Blaster/Weapon/ProjectileRocket.cpp b/Source/Blaster/Weapon/ProjectileRocket.cpp index 8eb91c1..5a62951 100644 --- a/Source/Blaster/Weapon/ProjectileRocket.cpp +++ b/Source/Blaster/Weapon/ProjectileRocket.cpp @@ -16,7 +16,7 @@ AProjectileRocket::AProjectileRocket() ProjectileMesh->SetupAttachment(RootComponent); ProjectileMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); - RocketMovementComponent = CreateDefaultSubobject("RocketMovementComponent"); + RocketMovementComponent = CreateDefaultSubobject(TEXT("RocketMovementComponent")); RocketMovementComponent->bRotationFollowsVelocity = true; RocketMovementComponent->SetIsReplicated(true); } diff --git a/Source/Blaster/Weapon/ProjectileWeapon.cpp b/Source/Blaster/Weapon/ProjectileWeapon.cpp index ffe7e46..1262073 100644 --- a/Source/Blaster/Weapon/ProjectileWeapon.cpp +++ b/Source/Blaster/Weapon/ProjectileWeapon.cpp @@ -48,8 +48,7 @@ void AProjectileWeapon::Fire(const FVector& HitTarget) SpawnedProjectile = World->SpawnActor(ServerSideRewindProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams); SpawnedProjectile->bUseServerSideRewind = true; SpawnedProjectile->TraceStart = SocketTransform.GetLocation(); - SpawnedProjectile->InitialVelocity= SpawnedProjectile->GetActorForwardVector() * SpawnedProjectile->InitialSpeed; - SpawnedProjectile->Damage = Damage; + SpawnedProjectile->InitialVelocity = SpawnedProjectile->GetActorForwardVector() * SpawnedProjectile->InitialSpeed; } else // Client, not locally controlled - spawn non-replicated projectile, no SSR { diff --git a/Source/Blaster/Weapon/RocketMovementComponent.cpp b/Source/Blaster/Weapon/RocketMovementComponent.cpp index a75878f..8fed69a 100644 --- a/Source/Blaster/Weapon/RocketMovementComponent.cpp +++ b/Source/Blaster/Weapon/RocketMovementComponent.cpp @@ -3,11 +3,10 @@ #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) { Super::HandleBlockingHit(Hit, TimeTick, MoveDelta, SubTickTimeRemaining); - return EHandleBlockingHitResult::AdvanceNextSubstep; } diff --git a/Source/Blaster/Weapon/Shotgun.cpp b/Source/Blaster/Weapon/Shotgun.cpp index 0333d54..b1a612a 100644 --- a/Source/Blaster/Weapon/Shotgun.cpp +++ b/Source/Blaster/Weapon/Shotgun.cpp @@ -114,7 +114,6 @@ void AShotgun::ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray(Owner) : OwnerCharacter; - if (OwnerCharacter && OwnerCharacter->GetPrimaryWeapon() && OwnerCharacter->GetPrimaryWeapon() == this) - { - SetHUDAmmo(); - } - } -} - void AWeapon::SetHUDAmmo() { OwnerCharacter = OwnerCharacter == nullptr ? Cast(GetOwner()) : OwnerCharacter; @@ -169,6 +150,24 @@ void AWeapon::ClientAddAmmo_Implementation(int32 AmmoToAdd) SetHUDAmmo(); } +void AWeapon::OnRep_Owner() +{ + Super::OnRep_Owner(); + if (Owner == nullptr) + { + OwnerCharacter = nullptr; + OwnerController = nullptr; + } + else + { + OwnerCharacter = OwnerCharacter == nullptr ? Cast(Owner) : OwnerCharacter; + if (OwnerCharacter && OwnerCharacter->GetPrimaryWeapon() && OwnerCharacter->GetPrimaryWeapon() == this) + { + SetHUDAmmo(); + } + } +} + void AWeapon::SetWeaponState(EWeaponState State) { WeaponState = State; @@ -204,7 +203,7 @@ void AWeapon::OnRep_WeaponState() void AWeapon::OnEquipped() { ShowPickupWidget(false); - GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision); + AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision); WeaponMesh->SetSimulatePhysics(false); WeaponMesh->SetEnableGravity(false); 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(GetOwner()) : OwnerCharacter; + if (OwnerCharacter && bUseServerSideRewind) + { + OwnerController = OwnerController == nullptr ? Cast(OwnerCharacter->Controller) : OwnerController; + if (OwnerController && HasAuthority() && OwnerController->HighPingDelegate.IsBound()) + { + OwnerController->HighPingDelegate.RemoveDynamic(this, &AWeapon::OnPingTooHigh); + } + } +} + void AWeapon::OnEquippedSecondary() { ShowPickupWidget(false); - GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision); + AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision); WeaponMesh->SetSimulatePhysics(false); WeaponMesh->SetEnableGravity(false); 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(GetOwner()) : OwnerCharacter; - if (OwnerCharacter && bUseServerSideRewind) - { - OwnerController = OwnerController == nullptr ? Cast(OwnerCharacter->Controller) : OwnerController; - if (OwnerController && HasAuthority() && OwnerController->HighPingDelegate.IsBound()) - { - OwnerController->HighPingDelegate.RemoveDynamic(this, &AWeapon::OnPingTooHigh); - } - } -} - - - bool AWeapon::IsEmpty() { return Ammo <= 0;