diff --git a/Source/Blaster/Character/BlasterCharacter.cpp b/Source/Blaster/Character/BlasterCharacter.cpp index c1b5568..a07a6f3 100644 --- a/Source/Blaster/Character/BlasterCharacter.cpp +++ b/Source/Blaster/Character/BlasterCharacter.cpp @@ -437,7 +437,14 @@ void ABlasterCharacter::ServerEquipButtonPressed_Implementation() { if (Combat) { - Combat->EquipWeapon(OverlappingWeapon); + if (OverlappingWeapon) + { + Combat->EquipWeapon(OverlappingWeapon); + } + else if (Combat->ShouldSwapWeapons()) + { + Combat->SwapWeapons(); + } } } @@ -637,6 +644,10 @@ void ABlasterCharacter::HideCameraIfCharacterClose() { Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = true; } + if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh()) + { + Combat->SecondaryWeapon->GetWeaponMesh()->bOwnerNoSee = true; + } } else { @@ -645,6 +656,10 @@ void ABlasterCharacter::HideCameraIfCharacterClose() { Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = false; } + if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh()) + { + Combat->SecondaryWeapon->GetWeaponMesh()->bOwnerNoSee = false; + } } } diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index 7f97456..73c0703 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -173,6 +173,27 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) Character->bUseControllerRotationYaw = true; } +void UCombatComponent::SwapWeapons() +{ + AWeapon* TempWeapon = PrimaryWeapon; + PrimaryWeapon = SecondaryWeapon; + SecondaryWeapon = TempWeapon; + + PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToRightHand(PrimaryWeapon); + PrimaryWeapon->SetHUDAmmo(); + UpdateCarriedAmmo(); + PlayEquipWeaponSound(PrimaryWeapon); + + SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); + AttachActorToBackpack(SecondaryWeapon); +} + +bool UCombatComponent::ShouldSwapWeapons() +{ + return PrimaryWeapon != nullptr && SecondaryWeapon != nullptr; +} + void UCombatComponent::EquipPrimaryWeapon(AWeapon* WeaponToEquip) { if (WeaponToEquip == nullptr) return; @@ -191,12 +212,34 @@ void UCombatComponent::EquipPrimaryWeapon(AWeapon* WeaponToEquip) void UCombatComponent::EquipSecondaryWeapon(AWeapon* WeaponToEquip) { if (WeaponToEquip == nullptr) return; - SecondaryWeapon = WeaponToEquip; - SecondaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); AttachActorToBackpack(WeaponToEquip); - PrimaryWeapon->SetOwner(Character); PlayEquipWeaponSound(SecondaryWeapon); + SecondaryWeapon->SetOwner(Character); +} + +void UCombatComponent::OnRep_PrimaryWeapon() +{ + if (PrimaryWeapon && Character) + { + PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); + AttachActorToRightHand(PrimaryWeapon); + Character->GetCharacterMovement()->bOrientRotationToMovement = false; + Character->bUseControllerRotationYaw = true; + PlayEquipWeaponSound(PrimaryWeapon); + PrimaryWeapon->SetHUDAmmo(); + } +} + +void UCombatComponent::OnRep_SecondaryWeapon() +{ + if (SecondaryWeapon && Character) + { + SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary); + AttachActorToBackpack(SecondaryWeapon); + PlayEquipWeaponSound(SecondaryWeapon); + } } void UCombatComponent::DropPrimaryWeapon() @@ -495,28 +538,6 @@ void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade) } } -void UCombatComponent::OnRep_PrimaryWeapon() -{ - if (PrimaryWeapon && Character) - { - PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToRightHand(PrimaryWeapon); - Character->GetCharacterMovement()->bOrientRotationToMovement = false; - Character->bUseControllerRotationYaw = true; - PlayEquipWeaponSound(PrimaryWeapon); - } -} - -void UCombatComponent::OnRep_SecondaryWeapon() -{ - if (SecondaryWeapon && Character) - { - SecondaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - AttachActorToBackpack(SecondaryWeapon); - PlayEquipWeaponSound(SecondaryWeapon); - } -} - void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult) { FVector2D ViewportSize; diff --git a/Source/Blaster/Components/CombatComponent.h b/Source/Blaster/Components/CombatComponent.h index 02cf909..bf55c6d 100644 --- a/Source/Blaster/Components/CombatComponent.h +++ b/Source/Blaster/Components/CombatComponent.h @@ -23,6 +23,7 @@ public: virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; void EquipWeapon(class AWeapon* WeaponToEquip); + void SwapWeapons(); void Reload(); UFUNCTION(BlueprintCallable) void FinishedReloading(); @@ -43,8 +44,6 @@ public: UFUNCTION(Server, Reliable) void ServerLaunchGrenade(const FVector_NetQuantize& Target); - FORCEINLINE int32 GetGrenades() const { return Grenades; } - void PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount); protected: @@ -209,4 +208,9 @@ private: int32 MaxGrenades = 4; void UpdateHUDGrenades(); + +public: + FORCEINLINE int32 GetGrenades() const { return Grenades; } + bool ShouldSwapWeapons(); + }; diff --git a/Source/Blaster/Weapon/Weapon.cpp b/Source/Blaster/Weapon/Weapon.cpp index fff9b8c..a7a4b3f 100644 --- a/Source/Blaster/Weapon/Weapon.cpp +++ b/Source/Blaster/Weapon/Weapon.cpp @@ -148,40 +148,86 @@ void AWeapon::OnRep_Ammo() void AWeapon::SetWeaponState(EWeaponState State) { WeaponState = State; + OnWeaponStateSet(); +} + +void AWeapon::OnWeaponStateSet() +{ switch (WeaponState) { case EWeaponState::EWS_Equipped: - ShowPickupWidget(false); - GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision); - WeaponMesh->SetSimulatePhysics(false); - WeaponMesh->SetEnableGravity(false); - WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); - if (IsSMG()) - { - WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); - WeaponMesh->SetEnableGravity(true); - WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); - } - EnableCustomDepth(false); + OnEquipped(); + break; + case EWeaponState::EWS_EquippedSecondary: + OnEquippedSecondary(); break; case EWeaponState::EWS_Dropped: - 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); + OnDropped(); break; } } +void AWeapon::OnRep_WeaponState() +{ + OnWeaponStateSet(); +} + +void AWeapon::OnEquipped() +{ + ShowPickupWidget(false); + GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision); + WeaponMesh->SetSimulatePhysics(false); + WeaponMesh->SetEnableGravity(false); + WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); + if (IsSMG()) + { + WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + WeaponMesh->SetEnableGravity(true); + WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); + } + EnableCustomDepth(false); +} + +void AWeapon::OnEquippedSecondary() +{ + ShowPickupWidget(false); + GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision); + WeaponMesh->SetSimulatePhysics(false); + WeaponMesh->SetEnableGravity(false); + WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); + if (IsSMG()) + { + WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); + WeaponMesh->SetEnableGravity(true); + WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); + } + EnableCustomDepth(true); + if (WeaponMesh) + { + WeaponMesh->SetCustomDepthStencilValue(CUSTOM_DEPTH_TAN); + WeaponMesh->MarkRenderStateDirty(); + } +} + +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); +} + + + bool AWeapon::IsEmpty() { return Ammo <= 0; @@ -192,37 +238,6 @@ bool AWeapon::IsFull() return Ammo == MagCapacity; } -void AWeapon::OnRep_WeaponState() -{ - switch (WeaponState) - { - case EWeaponState::EWS_Equipped: - ShowPickupWidget(false); - WeaponMesh->SetSimulatePhysics(false); - WeaponMesh->SetEnableGravity(false); - WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); - if (IsSMG()) - { - WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); - WeaponMesh->SetEnableGravity(true); - WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); - } - EnableCustomDepth(false); - break; - case EWeaponState::EWS_Dropped: - 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); - break; - } -} - void AWeapon::ShowPickupWidget(bool bShowWidget) { if (PickupWidget) diff --git a/Source/Blaster/Weapon/Weapon.h b/Source/Blaster/Weapon/Weapon.h index c4c0a13..a0c1322 100644 --- a/Source/Blaster/Weapon/Weapon.h +++ b/Source/Blaster/Weapon/Weapon.h @@ -12,6 +12,7 @@ enum class EWeaponState : uint8 { EWS_Initial UMETA(DisplayName = "Initial State"), EWS_Equipped UMETA(DisplayName = "Equipped"), + EWS_EquippedSecondary UMETA(DisplayName = "Equipped Secondary"), EWS_Dropped UMETA(DisplayName = "Dropped"), EWS_MAX UMETA(DisplayName = "DefaultMAX") @@ -74,6 +75,11 @@ public: protected: virtual void BeginPlay() override; + virtual void OnWeaponStateSet(); + virtual void OnEquipped(); + virtual void OnDropped(); + virtual void OnEquippedSecondary(); + UFUNCTION() virtual void OnSphereOverlap( UPrimitiveComponent* OverlappedComponent,