diff --git a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset index 76e8702..f49ef55 100644 Binary files a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset and b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Skeleton.uasset differ diff --git a/Source/Blaster/Character/BlasterAnimInstance.cpp b/Source/Blaster/Character/BlasterAnimInstance.cpp index 1856f8c..61a0b19 100644 --- a/Source/Blaster/Character/BlasterAnimInstance.cpp +++ b/Source/Blaster/Character/BlasterAnimInstance.cpp @@ -32,7 +32,7 @@ void UBlasterAnimInstance::NativeUpdateAnimation(float DeltaTime) bIsInAir = BlasterCharacter->GetCharacterMovement()->IsFalling(); bIsAccelerating = BlasterCharacter->GetCharacterMovement()->GetCurrentAcceleration().Size() > 0.f ? true : false; bWeaponEquipped = BlasterCharacter->IsWeaponEquipped(); - EquippedWeapon = BlasterCharacter->GetEquippedWeapon(); + EquippedWeapon = BlasterCharacter->GetPrimaryWeapon(); bIsCrouched = BlasterCharacter->bIsCrouched; bAiming = BlasterCharacter->IsAiming(); TurningInPlace = BlasterCharacter->GetTurningInPlace(); diff --git a/Source/Blaster/Character/BlasterCharacter.cpp b/Source/Blaster/Character/BlasterCharacter.cpp index 2503653..c1b5568 100644 --- a/Source/Blaster/Character/BlasterCharacter.cpp +++ b/Source/Blaster/Character/BlasterCharacter.cpp @@ -84,9 +84,9 @@ void ABlasterCharacter::OnRep_ReplicatedMovement() void ABlasterCharacter::Eliminated() { - if (Combat && Combat->EquippedWeapon) + if (Combat && Combat->PrimaryWeapon) { - Combat->EquippedWeapon->Dropped(); + Combat->PrimaryWeapon->Dropped(); } MulticastEliminated(); GetWorldTimerManager().SetTimer( @@ -146,7 +146,7 @@ void ABlasterCharacter::MulticastEliminated_Implementation() GetActorLocation() ); } - if (IsLocallyControlled() && GetEquippedWeapon() && GetEquippedWeapon()->IsSniper() && IsAiming()) + if (IsLocallyControlled() && GetPrimaryWeapon() && GetPrimaryWeapon()->IsSniper() && IsAiming()) { ShowSniperScopeWidget(false); } @@ -173,9 +173,9 @@ void ABlasterCharacter::Destroyed() ABlasterGameMode* BlasterGameMode = Cast(UGameplayStatics::GetGameMode(this)); bool bMatchNotInProgress = BlasterGameMode && BlasterGameMode->GetMatchState() != MatchState::InProgress; - if (Combat && Combat->EquippedWeapon && bMatchNotInProgress) + if (Combat && Combat->PrimaryWeapon && bMatchNotInProgress) { - Combat->EquippedWeapon->Destroy(); + Combat->PrimaryWeapon->Destroy(); } } @@ -267,7 +267,7 @@ void ABlasterCharacter::PostInitializeComponents() void ABlasterCharacter::PlayFireMontage(bool bAiming) { - if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; + if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); if (AnimInstance && FireWeaponMontage) @@ -281,7 +281,7 @@ void ABlasterCharacter::PlayFireMontage(bool bAiming) void ABlasterCharacter::PlayReloadMontage() { - if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; + if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); if (AnimInstance && ReloadMontage) @@ -289,7 +289,7 @@ void ABlasterCharacter::PlayReloadMontage() AnimInstance->Montage_Play(ReloadMontage); FName SectionName; - switch (Combat->EquippedWeapon->GetWeaponType()) + switch (Combat->PrimaryWeapon->GetWeaponType()) { case EWeaponType::EWT_AssaultRifle: SectionName = FName("Rifle"); @@ -341,7 +341,7 @@ void ABlasterCharacter::PlayThrowGrenadeMontage() void ABlasterCharacter::PlayHitReactMontage() { - if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; + if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance(); if (AnimInstance && HitReactMontage) @@ -429,20 +429,16 @@ void ABlasterCharacter::EquipButtonPressed() if (bDisableGameplay) return; if (Combat) { - if (HasAuthority()) - { - Combat->EquipWeapon(OverlappingWeapon); - } - else - { - ServerEquipButtonPressed(); - } + ServerEquipButtonPressed(); } } void ABlasterCharacter::ServerEquipButtonPressed_Implementation() { - EquipButtonPressed(); + if (Combat) + { + Combat->EquipWeapon(OverlappingWeapon); + } } void ABlasterCharacter::CrouchButtonPressed() @@ -502,7 +498,7 @@ float ABlasterCharacter::CalculateSpeed() void ABlasterCharacter::AimOffset(float DeltaTime) { - if (Combat && Combat->EquippedWeapon == nullptr) return; + if (Combat && Combat->PrimaryWeapon == nullptr) return; float Speed = CalculateSpeed(); bool bIsInAir = GetCharacterMovement()->IsFalling(); @@ -545,7 +541,7 @@ void ABlasterCharacter::CalculateAO_Pitch() void ABlasterCharacter::SimProxiesTurn() { - if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return; + if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return; bRotateRootBone = false; float Speed = CalculateSpeed(); if (Speed > 0.f) @@ -637,17 +633,17 @@ void ABlasterCharacter::HideCameraIfCharacterClose() if ((FollowCamera->GetComponentLocation() - GetActorLocation()).Size() < CameraThreshold) { GetMesh()->SetVisibility(false); - if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh()) + if (Combat && Combat->PrimaryWeapon && Combat->PrimaryWeapon->GetWeaponMesh()) { - Combat->EquippedWeapon->GetWeaponMesh()->bOwnerNoSee = true; + Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = true; } } else { GetMesh()->SetVisibility(true); - if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh()) + if (Combat && Combat->PrimaryWeapon && Combat->PrimaryWeapon->GetWeaponMesh()) { - Combat->EquippedWeapon->GetWeaponMesh()->bOwnerNoSee = false; + Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = false; } } } @@ -691,10 +687,10 @@ void ABlasterCharacter::UpdateHUDShield() void ABlasterCharacter::UpdateHUDAmmo() { BlasterPlayerController = BlasterPlayerController == nullptr ? Cast(Controller) : BlasterPlayerController; - if (BlasterPlayerController && Combat && Combat->EquippedWeapon) + if (BlasterPlayerController && Combat && Combat->PrimaryWeapon) { BlasterPlayerController->SetHUDCarriedAmmo(Combat->CarriedAmmo); - BlasterPlayerController->SetHUDWeaponAmmo(Combat->EquippedWeapon->GetAmmo()); + BlasterPlayerController->SetHUDWeaponAmmo(Combat->PrimaryWeapon->GetAmmo()); } } @@ -775,7 +771,7 @@ void ABlasterCharacter::OnRep_OverlappingWeapon(AWeapon* LastWeapon) bool ABlasterCharacter::IsWeaponEquipped() { - return Combat && Combat->EquippedWeapon; + return Combat && Combat->PrimaryWeapon; } bool ABlasterCharacter::IsAiming() @@ -783,10 +779,10 @@ bool ABlasterCharacter::IsAiming() return Combat && Combat->bAiming; } -AWeapon* ABlasterCharacter::GetEquippedWeapon() +AWeapon* ABlasterCharacter::GetPrimaryWeapon() { if (Combat == nullptr) return nullptr; - return Combat->EquippedWeapon; + return Combat->PrimaryWeapon; } FVector ABlasterCharacter::GetHitTarget() const diff --git a/Source/Blaster/Character/BlasterCharacter.h b/Source/Blaster/Character/BlasterCharacter.h index 5e257fb..f12c88c 100644 --- a/Source/Blaster/Character/BlasterCharacter.h +++ b/Source/Blaster/Character/BlasterCharacter.h @@ -219,7 +219,7 @@ public: bool IsAiming(); FORCEINLINE float GetAO_Yaw() const { return AO_Yaw; } FORCEINLINE float GetAO_Pitch() const { return AO_Pitch; } - AWeapon* GetEquippedWeapon(); + AWeapon* GetPrimaryWeapon(); FORCEINLINE ETurningInPlace GetTurningInPlace() const { return TurningInPlace; } FVector GetHitTarget() const; FORCEINLINE UCameraComponent* GetFollowCamera() const { return FollowCamera; } diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index 8e9aeb9..7f97456 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -24,7 +24,8 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray& Out { Super::GetLifetimeReplicatedProps(OutLifetimeProps); - DOREPLIFETIME(UCombatComponent, EquippedWeapon); + DOREPLIFETIME(UCombatComponent, PrimaryWeapon); + DOREPLIFETIME(UCombatComponent, SecondaryWeapon); DOREPLIFETIME(UCombatComponent, bAiming); DOREPLIFETIME_CONDITION(UCombatComponent, CarriedAmmo, COND_OwnerOnly); DOREPLIFETIME(UCombatComponent, CombatState); @@ -38,7 +39,7 @@ void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount) CarriedAmmoMap[WeaponType] = FMath::Clamp(CarriedAmmoMap[WeaponType] + AmmoAmount, 0, MaxCarriedAmmo); UpdateCarriedAmmo(); } - if (EquippedWeapon && EquippedWeapon->IsEmpty() && EquippedWeapon->GetWeaponType() == WeaponType) + if (PrimaryWeapon && PrimaryWeapon->IsEmpty() && PrimaryWeapon->GetWeaponType() == WeaponType) { Reload(); } @@ -82,7 +83,7 @@ void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActo void UCombatComponent::FireButtonPressed(bool bPressed) { bFireButtonPressed = bPressed; - if (bFireButtonPressed && EquippedWeapon) + if (bFireButtonPressed && PrimaryWeapon) { Fire(); } @@ -102,7 +103,7 @@ void UCombatComponent::Fire() { bCanFire = false; ServerFire(HitTarget); - if (EquippedWeapon) + if (PrimaryWeapon) { CrosshairShootingFactor = .75f; } @@ -112,20 +113,20 @@ void UCombatComponent::Fire() void UCombatComponent::StartFireTimer() { - if (EquippedWeapon == nullptr || Character == nullptr) return; + if (PrimaryWeapon == nullptr || Character == nullptr) return; Character->GetWorldTimerManager().SetTimer( FireTimer, this, &UCombatComponent::FireTimerFinished, - EquippedWeapon->FireDelay + PrimaryWeapon->FireDelay ); } void UCombatComponent::FireTimerFinished() { - if (EquippedWeapon == nullptr) return; + if (PrimaryWeapon == nullptr) return; bCanFire = true; - if (bFireButtonPressed && EquippedWeapon->bAutomatic) + if (bFireButtonPressed && PrimaryWeapon->bAutomatic) { Fire(); } @@ -139,18 +140,18 @@ void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& Trac void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget) { - if (EquippedWeapon == nullptr) return; - if (Character && CombatState == ECombatState::ECS_Reloading && EquippedWeapon->IsShotgun()) + if (PrimaryWeapon == nullptr) return; + if (Character && CombatState == ECombatState::ECS_Reloading && PrimaryWeapon->IsShotgun()) { Character->PlayFireMontage(bAiming); - EquippedWeapon->Fire(TraceHitTarget); + PrimaryWeapon->Fire(TraceHitTarget); CombatState = ECombatState::ECS_Unoccupied; return; } if (Character && CombatState == ECombatState::ECS_Unoccupied) { Character->PlayFireMontage(bAiming); - EquippedWeapon->Fire(TraceHitTarget); + PrimaryWeapon->Fire(TraceHitTarget); } } @@ -158,26 +159,51 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) { if (Character == nullptr || WeaponToEquip == nullptr) return; if (CombatState != ECombatState::ECS_Unoccupied) return; - - DropEquippedWeapon(); - EquippedWeapon = WeaponToEquip; - EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToRightHand(EquippedWeapon); - EquippedWeapon->SetOwner(Character); - EquippedWeapon->SetHUDAmmo(); - UpdateCarriedAmmo(); - PlayEquipWeaponSound(); - ReloadEmptyWeapon(); + + if (PrimaryWeapon != nullptr && SecondaryWeapon == nullptr) + { + EquipSecondaryWeapon(WeaponToEquip); + } + else + { + EquipPrimaryWeapon(WeaponToEquip); + } Character->GetCharacterMovement()->bOrientRotationToMovement = false; Character->bUseControllerRotationYaw = true; } -void UCombatComponent::DropEquippedWeapon() +void UCombatComponent::EquipPrimaryWeapon(AWeapon* WeaponToEquip) { - if (EquippedWeapon) + if (WeaponToEquip == nullptr) return; + + DropPrimaryWeapon(); + PrimaryWeapon = WeaponToEquip; + PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToRightHand(PrimaryWeapon); + PrimaryWeapon->SetOwner(Character); + PrimaryWeapon->SetHUDAmmo(); + UpdateCarriedAmmo(); + PlayEquipWeaponSound(PrimaryWeapon); + ReloadEmptyWeapon(); +} + +void UCombatComponent::EquipSecondaryWeapon(AWeapon* WeaponToEquip) +{ + if (WeaponToEquip == nullptr) return; + + SecondaryWeapon = WeaponToEquip; + SecondaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToBackpack(WeaponToEquip); + PrimaryWeapon->SetOwner(Character); + PlayEquipWeaponSound(SecondaryWeapon); +} + +void UCombatComponent::DropPrimaryWeapon() +{ + if (PrimaryWeapon) { - EquippedWeapon->Dropped(); + PrimaryWeapon->Dropped(); } } @@ -193,8 +219,8 @@ void UCombatComponent::AttachActorToRightHand(AActor* ActorToAttach) void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach) { - if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || EquippedWeapon == nullptr) return; - bool bUsePistolSocket = EquippedWeapon->IsPistol() || EquippedWeapon->IsSMG(); + if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || PrimaryWeapon == nullptr) return; + bool bUsePistolSocket = PrimaryWeapon->IsPistol() || PrimaryWeapon->IsSMG(); FName SocketName = bUsePistolSocket ? FName("LeftHandPistolSocket") : FName("LeftHandSocket"); const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(SocketName); if (HandSocket) @@ -203,12 +229,22 @@ void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach) } } +void UCombatComponent::AttachActorToBackpack(AActor* ActorToAttach) +{ + if (Character == nullptr || Character->GetMesh() == nullptr|| ActorToAttach == nullptr) return; + const USkeletalMeshSocket* BackpackSocket = Character->GetMesh()->GetSocketByName(FName("BackpackSocket")); + if (BackpackSocket) + { + BackpackSocket->AttachActor(ActorToAttach, Character->GetMesh()); + } +} + void UCombatComponent::UpdateCarriedAmmo() { - if (EquippedWeapon == nullptr) return; - if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) + if (PrimaryWeapon == nullptr) return; + if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType())) { - CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; + CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()]; } Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; @@ -218,13 +254,13 @@ void UCombatComponent::UpdateCarriedAmmo() } } -void UCombatComponent::PlayEquipWeaponSound() +void UCombatComponent::PlayEquipWeaponSound(const AWeapon* Weapon) { - if (Character && EquippedWeapon && EquippedWeapon->EquipSound) + if (Character && Weapon && Weapon->EquipSound) { UGameplayStatics::PlaySoundAtLocation( this, - EquippedWeapon->EquipSound, + Weapon->EquipSound, Character->GetActorLocation() ); } @@ -232,7 +268,7 @@ void UCombatComponent::PlayEquipWeaponSound() void UCombatComponent::ReloadEmptyWeapon() { - if (EquippedWeapon && EquippedWeapon->IsEmpty()) + if (PrimaryWeapon && PrimaryWeapon->IsEmpty()) { Reload(); } @@ -248,10 +284,10 @@ void UCombatComponent::Reload() void UCombatComponent::ServerReload_Implementation() { - if (Character == nullptr || EquippedWeapon == nullptr) return; + if (Character == nullptr || PrimaryWeapon == nullptr) return; // return if weapon mag is at max capacity - if (EquippedWeapon->GetAmmo() == EquippedWeapon->GetMagCapacity()) return; + if (PrimaryWeapon->GetAmmo() == PrimaryWeapon->GetMagCapacity()) return; CombatState = ECombatState::ECS_Reloading; HandleReload(); @@ -273,38 +309,38 @@ void UCombatComponent::FinishedReloading() void UCombatComponent::UpdateAmmoValues() { - if (Character == nullptr || EquippedWeapon == nullptr) return; + if (Character == nullptr || PrimaryWeapon == nullptr) return; int32 ReloadAmount = AmountToReload(); - if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) + if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType())) { - CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= ReloadAmount; - CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; + CarriedAmmoMap[PrimaryWeapon->GetWeaponType()] -= ReloadAmount; + CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()]; } Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; if (Controller) { Controller->SetHUDCarriedAmmo(CarriedAmmo); } - EquippedWeapon->AddAmmo(-ReloadAmount); + PrimaryWeapon->AddAmmo(-ReloadAmount); } void UCombatComponent::UpdateShotgunAmmoValues() { - if (Character == nullptr || EquippedWeapon == nullptr) return; + if (Character == nullptr || PrimaryWeapon == nullptr) return; - if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) + if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType())) { - CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= 1; - CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; + CarriedAmmoMap[PrimaryWeapon->GetWeaponType()] -= 1; + CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()]; } Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; if (Controller) { Controller->SetHUDCarriedAmmo(CarriedAmmo); } - EquippedWeapon->AddAmmo(-1); + PrimaryWeapon->AddAmmo(-1); bCanFire = true; - if (EquippedWeapon->IsFull() || CarriedAmmo == 0) + if (PrimaryWeapon->IsFull() || CarriedAmmo == 0) { JumpToShotgunEnd(); } @@ -323,7 +359,7 @@ void UCombatComponent::JumpToShotgunEnd() void UCombatComponent::ThrowGrenadeFinished() { CombatState = ECombatState::ECS_Unoccupied; - AttachActorToRightHand(EquippedWeapon); + AttachActorToRightHand(PrimaryWeapon); } void UCombatComponent::LaunchGrenade() @@ -375,7 +411,7 @@ void UCombatComponent::OnRep_CombatState() if (Character && !Character->IsLocallyControlled()) { Character->PlayThrowGrenadeMontage(); - AttachActorToLeftHand(EquippedWeapon); + AttachActorToLeftHand(PrimaryWeapon); ShowAttachedGrenade(true); } break; @@ -389,12 +425,12 @@ void UCombatComponent::HandleReload() int32 UCombatComponent::AmountToReload() { - if (EquippedWeapon == nullptr) return 0; - int32 RoomInMag = EquippedWeapon->GetMagCapacity() - EquippedWeapon->GetAmmo(); + if (PrimaryWeapon == nullptr) return 0; + int32 RoomInMag = PrimaryWeapon->GetMagCapacity() - PrimaryWeapon->GetAmmo(); - if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) + if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType())) { - int32 AmountCarried = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; + int32 AmountCarried = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()]; int32 Least = FMath::Min(RoomInMag, AmountCarried); return FMath::Clamp(RoomInMag, 0, Least); } @@ -404,12 +440,12 @@ int32 UCombatComponent::AmountToReload() void UCombatComponent::ThrowGrenade() { if (Grenades == 0) return; - if (CombatState != ECombatState::ECS_Unoccupied || EquippedWeapon == nullptr) return; + if (CombatState != ECombatState::ECS_Unoccupied || PrimaryWeapon == nullptr) return; CombatState = ECombatState::ECS_ThrowingGrenade; if (Character) { Character->PlayThrowGrenadeMontage(); - AttachActorToLeftHand(EquippedWeapon); + AttachActorToLeftHand(PrimaryWeapon); ShowAttachedGrenade(true); } if (Character && !Character->HasAuthority()) @@ -430,7 +466,7 @@ void UCombatComponent::ServerThrowGrenade_Implementation() if (Character) { Character->PlayThrowGrenadeMontage(); - AttachActorToLeftHand(EquippedWeapon); + AttachActorToLeftHand(PrimaryWeapon); ShowAttachedGrenade(true); } Grenades = FMath::Clamp(Grenades -1, 0, MaxGrenades); @@ -459,15 +495,25 @@ void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade) } } -void UCombatComponent::OnRep_EquippedWeapon() +void UCombatComponent::OnRep_PrimaryWeapon() { - if (EquippedWeapon && Character) + if (PrimaryWeapon && Character) { - EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToRightHand(EquippedWeapon); + PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToRightHand(PrimaryWeapon); Character->GetCharacterMovement()->bOrientRotationToMovement = false; Character->bUseControllerRotationYaw = true; - PlayEquipWeaponSound(); + PlayEquipWeaponSound(PrimaryWeapon); + } +} + +void UCombatComponent::OnRep_SecondaryWeapon() +{ + if (SecondaryWeapon && Character) + { + SecondaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToBackpack(SecondaryWeapon); + PlayEquipWeaponSound(SecondaryWeapon); } } @@ -530,13 +576,13 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime) HUD = HUD == nullptr ? Cast(Controller->GetHUD()) : HUD; if (HUD) { - if (EquippedWeapon) + if (PrimaryWeapon) { - HUDPackage.CrosshairsCenter = EquippedWeapon->CrosshairsCenter; - HUDPackage.CrosshairsLeft = EquippedWeapon->CrosshairsLeft; - HUDPackage.CrosshairsRight = EquippedWeapon->CrosshairsRight; - HUDPackage.CrosshairsBottom = EquippedWeapon->CrosshairsBottom; - HUDPackage.CrosshairsTop = EquippedWeapon->CrosshairsTop; + HUDPackage.CrosshairsCenter = PrimaryWeapon->CrosshairsCenter; + HUDPackage.CrosshairsLeft = PrimaryWeapon->CrosshairsLeft; + HUDPackage.CrosshairsRight = PrimaryWeapon->CrosshairsRight; + HUDPackage.CrosshairsBottom = PrimaryWeapon->CrosshairsBottom; + HUDPackage.CrosshairsTop = PrimaryWeapon->CrosshairsTop; } else { @@ -590,11 +636,11 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime) void UCombatComponent::InterpFOV(float DeltaTime) { - if (EquippedWeapon == nullptr) return; + if (PrimaryWeapon == nullptr) return; if (bAiming) { - CurrentFOV = FMath::FInterpTo(CurrentFOV, EquippedWeapon->GetZoomedFOV(), DeltaTime, EquippedWeapon->GetZoomInterpSpeed()); + CurrentFOV = FMath::FInterpTo(CurrentFOV, PrimaryWeapon->GetZoomedFOV(), DeltaTime, PrimaryWeapon->GetZoomInterpSpeed()); } else { @@ -608,14 +654,14 @@ void UCombatComponent::InterpFOV(float DeltaTime) void UCombatComponent::SetAiming(bool bIsAiming) { - if (Character == nullptr || EquippedWeapon == nullptr) return; + if (Character == nullptr || PrimaryWeapon == nullptr) return; bAiming = bIsAiming; ServerSetAiming(bIsAiming); if (Character) { Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed; } - if (Character->IsLocallyControlled() && EquippedWeapon->IsSniper()) + if (Character->IsLocallyControlled() && PrimaryWeapon->IsSniper()) { Character->ShowSniperScopeWidget(bIsAiming); } @@ -632,10 +678,10 @@ void UCombatComponent::ServerSetAiming_Implementation(bool bIsAiming) bool UCombatComponent::CanFire() { - if (EquippedWeapon == nullptr) return false; - if (EquippedWeapon->IsEmpty()) return false; + if (PrimaryWeapon == nullptr) return false; + if (PrimaryWeapon->IsEmpty()) return false; if (!bCanFire) return false; - if (CombatState == ECombatState::ECS_Reloading && EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true; + if (CombatState == ECombatState::ECS_Reloading && PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true; return CombatState == ECombatState::ECS_Unoccupied; } @@ -647,8 +693,8 @@ void UCombatComponent::OnRep_CarriedAmmo() Controller->SetHUDCarriedAmmo(CarriedAmmo); } bool bJumpToShotgunEnd = CombatState == ECombatState::ECS_Reloading && - EquippedWeapon != nullptr && - EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun && + PrimaryWeapon != nullptr && + PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun && CarriedAmmo == 0; if (bJumpToShotgunEnd) diff --git a/Source/Blaster/Components/CombatComponent.h b/Source/Blaster/Components/CombatComponent.h index a023908..02cf909 100644 --- a/Source/Blaster/Components/CombatComponent.h +++ b/Source/Blaster/Components/CombatComponent.h @@ -55,7 +55,10 @@ protected: void ServerSetAiming(bool bIsAiming); UFUNCTION() - void OnRep_EquippedWeapon(); + void OnRep_PrimaryWeapon(); + UFUNCTION() + void OnRep_SecondaryWeapon(); + void Fire(); UFUNCTION(Server, Reliable) @@ -82,23 +85,31 @@ protected: UPROPERTY(EditAnywhere) TSubclassOf GrenadeClass; - void DropEquippedWeapon(); + void DropPrimaryWeapon(); void AttachActorToRightHand(AActor* ActorToAttach); void AttachActorToLeftHand(AActor* ActorToAttach); + void AttachActorToBackpack(AActor* ActorToAttach); void UpdateCarriedAmmo(); - void PlayEquipWeaponSound(); + void PlayEquipWeaponSound(const AWeapon* Weapon); void ReloadEmptyWeapon(); void ShowAttachedGrenade(bool bShowGrenade); + void EquipPrimaryWeapon(AWeapon* WeaponToEquip); + void EquipSecondaryWeapon(AWeapon* WeaponToEquip); private: UPROPERTY() - class ABlasterCharacter* Character; + ABlasterCharacter* Character; + UPROPERTY() class ABlasterPlayerController* Controller; - UPROPERTY() - class ABlasterHUD* HUD; - UPROPERTY(ReplicatedUsing=OnRep_EquippedWeapon) - class AWeapon* EquippedWeapon; + UPROPERTY() + ABlasterHUD* HUD; + + UPROPERTY(ReplicatedUsing=OnRep_PrimaryWeapon) + AWeapon* PrimaryWeapon; + + UPROPERTY(ReplicatedUsing=OnRep_SecondaryWeapon) + AWeapon* SecondaryWeapon; UPROPERTY(Replicated) bool bAiming; diff --git a/Source/Blaster/Weapon/Weapon.cpp b/Source/Blaster/Weapon/Weapon.cpp index 674a3b9..fff9b8c 100644 --- a/Source/Blaster/Weapon/Weapon.cpp +++ b/Source/Blaster/Weapon/Weapon.cpp @@ -105,9 +105,14 @@ void AWeapon::OnRep_Owner() { OwnerCharacter = nullptr; OwnerController = nullptr; - } else + } + else { - SetHUDAmmo(); + OwnerCharacter = OwnerCharacter == nullptr ? Cast(Owner) : OwnerCharacter; + if (OwnerCharacter && OwnerCharacter->GetPrimaryWeapon() && OwnerCharacter->GetPrimaryWeapon() == this) + { + SetHUDAmmo(); + } } }