diff --git a/Content/Assets/Animations/GrenadeToss.uasset b/Content/Assets/Animations/GrenadeToss.uasset index 8781637..cd68004 100644 Binary files a/Content/Assets/Animations/GrenadeToss.uasset and b/Content/Assets/Animations/GrenadeToss.uasset differ diff --git a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter.uasset b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter.uasset index 5e77a65..2ddf4da 100644 Binary files a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter.uasset and b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter.uasset differ diff --git a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Optimized.uasset b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Optimized.uasset index cd7de0e..623e0dc 100644 Binary files a/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Optimized.uasset and b/Content/Assets/LearningKit_Games/Assets/Characters/Character/Mesh/SK_EpicCharacter_Optimized.uasset differ 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 34440af..ba8b692 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/BlasterCharacter.cpp b/Source/Blaster/Character/BlasterCharacter.cpp index 97416e1..0d82de4 100644 --- a/Source/Blaster/Character/BlasterCharacter.cpp +++ b/Source/Blaster/Character/BlasterCharacter.cpp @@ -137,7 +137,7 @@ void ABlasterCharacter::MulticastEliminated_Implementation() GetActorLocation() ); } - if (IsLocallyControlled() && GetEquippedWeapon() && GetEquippedWeapon()->GetWeaponType() == EWeaponType::EWT_SniperRifle && IsAiming()) + if (IsLocallyControlled() && GetEquippedWeapon() && GetEquippedWeapon()->IsSniper() && IsAiming()) { ShowSniperScopeWidget(false); } diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index 69efc54..8a94b83 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -115,10 +115,7 @@ void UCombatComponent::FireTimerFinished() { Fire(); } - if (EquippedWeapon->IsEmpty()) - { - Reload(); - } + ReloadEmptyWeapon(); } void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& TraceHitTarget) @@ -129,7 +126,7 @@ 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->GetWeaponType() == EWeaponType::EWT_Shotgun) + if (Character && CombatState == ECombatState::ECS_Reloading && EquippedWeapon->IsShotgun()) { Character->PlayFireMontage(bAiming); EquippedWeapon->Fire(TraceHitTarget); @@ -147,20 +144,54 @@ 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(); + + Character->GetCharacterMovement()->bOrientRotationToMovement = false; + Character->bUseControllerRotationYaw = true; +} + +void UCombatComponent::DropEquippedWeapon() +{ if (EquippedWeapon) { EquippedWeapon->Dropped(); } - EquippedWeapon = WeaponToEquip; - EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped); +} + +void UCombatComponent::AttachActorToRightHand(AActor* ActorToAttach) +{ + if (Character == nullptr || Character->GetMesh() == nullptr|| ActorToAttach == nullptr) return; const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket")); if (HandSocket) { - HandSocket->AttachActor(EquippedWeapon, Character->GetMesh()); + HandSocket->AttachActor(ActorToAttach, Character->GetMesh()); } - EquippedWeapon->SetOwner(Character); - EquippedWeapon->SetHUDAmmo(); +} +void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach) +{ + 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) + { + HandSocket->AttachActor(ActorToAttach, Character->GetMesh()); + } +} + +void UCombatComponent::UpdateCarriedAmmo() +{ + if (EquippedWeapon == nullptr) return; if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) { CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; @@ -171,8 +202,11 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) { Controller->SetHUDCarriedAmmo(CarriedAmmo); } +} - if (EquippedWeapon->EquipSound) +void UCombatComponent::PlayEquipWeaponSound() +{ + if (Character && EquippedWeapon && EquippedWeapon->EquipSound) { UGameplayStatics::PlaySoundAtLocation( this, @@ -180,14 +214,14 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) Character->GetActorLocation() ); } +} - if (EquippedWeapon->IsEmpty()) +void UCombatComponent::ReloadEmptyWeapon() +{ + if (EquippedWeapon && EquippedWeapon->IsEmpty()) { Reload(); } - - Character->GetCharacterMovement()->bOrientRotationToMovement = false; - Character->bUseControllerRotationYaw = true; } void UCombatComponent::Reload() @@ -275,6 +309,7 @@ void UCombatComponent::JumpToShotgunEnd() void UCombatComponent::ThrowGrenadeFinished() { CombatState = ECombatState::ECS_Unoccupied; + AttachActorToRightHand(EquippedWeapon); } void UCombatComponent::OnRep_CombatState() @@ -294,6 +329,7 @@ void UCombatComponent::OnRep_CombatState() if (Character && !Character->IsLocallyControlled()) { Character->PlayThrowGrenadeMontage(); + AttachActorToLeftHand(EquippedWeapon); } break; } @@ -321,14 +357,12 @@ int32 UCombatComponent::AmountToReload() void UCombatComponent::ThrowGrenade() { if (CombatState != ECombatState::ECS_Unoccupied) return; - CombatState = ECombatState::ECS_ThrowingGrenade; - if (Character) { Character->PlayThrowGrenadeMontage(); + AttachActorToLeftHand(EquippedWeapon); } - if (Character && !Character->HasAuthority()) { ServerThrowGrenade(); @@ -338,10 +372,10 @@ void UCombatComponent::ThrowGrenade() void UCombatComponent::ServerThrowGrenade_Implementation() { CombatState = ECombatState::ECS_ThrowingGrenade; - if (Character) { Character->PlayThrowGrenadeMontage(); + AttachActorToLeftHand(EquippedWeapon); } } @@ -350,22 +384,10 @@ void UCombatComponent::OnRep_EquippedWeapon() if (EquippedWeapon && Character) { EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped); - const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket")); - if (HandSocket) - { - HandSocket->AttachActor(EquippedWeapon, Character->GetMesh()); - } + AttachActorToRightHand(EquippedWeapon); Character->GetCharacterMovement()->bOrientRotationToMovement = false; Character->bUseControllerRotationYaw = true; - - if (EquippedWeapon->EquipSound) - { - UGameplayStatics::PlaySoundAtLocation( - this, - EquippedWeapon->EquipSound, - Character->GetActorLocation() - ); - } + PlayEquipWeaponSound(); } } @@ -509,10 +531,11 @@ void UCombatComponent::SetAiming(bool bIsAiming) if (Character == nullptr || EquippedWeapon == nullptr) return; bAiming = bIsAiming; ServerSetAiming(bIsAiming); - - Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed; - - if (Character->IsLocallyControlled() && EquippedWeapon->GetWeaponType() == EWeaponType::EWT_SniperRifle) + if (Character) + { + Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed; + } + if (Character->IsLocallyControlled() && EquippedWeapon->IsSniper()) { Character->ShowSniperScopeWidget(bIsAiming); } diff --git a/Source/Blaster/Components/CombatComponent.h b/Source/Blaster/Components/CombatComponent.h index 937575a..bb246fe 100644 --- a/Source/Blaster/Components/CombatComponent.h +++ b/Source/Blaster/Components/CombatComponent.h @@ -67,6 +67,13 @@ protected: UFUNCTION(Server, Reliable) void ServerThrowGrenade(); + + void DropEquippedWeapon(); + void AttachActorToRightHand(AActor* ActorToAttach); + void AttachActorToLeftHand(AActor* ActorToAttach); + void UpdateCarriedAmmo(); + void PlayEquipWeaponSound(); + void ReloadEmptyWeapon(); private: UPROPERTY() class ABlasterCharacter* Character; diff --git a/Source/Blaster/Weapon/Weapon.cpp b/Source/Blaster/Weapon/Weapon.cpp index 3d592cf..f9a476f 100644 --- a/Source/Blaster/Weapon/Weapon.cpp +++ b/Source/Blaster/Weapon/Weapon.cpp @@ -151,7 +151,7 @@ void AWeapon::SetWeaponState(EWeaponState State) WeaponMesh->SetSimulatePhysics(false); WeaponMesh->SetEnableGravity(false); WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); - if (WeaponType == EWeaponType::EWT_SubmachineGun) + if (IsSMG()) { WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); WeaponMesh->SetEnableGravity(true); @@ -196,7 +196,7 @@ void AWeapon::OnRep_WeaponState() WeaponMesh->SetSimulatePhysics(false); WeaponMesh->SetEnableGravity(false); WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); - if (WeaponType == EWeaponType::EWT_SubmachineGun) + if (IsSMG()) { WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); WeaponMesh->SetEnableGravity(true); diff --git a/Source/Blaster/Weapon/Weapon.h b/Source/Blaster/Weapon/Weapon.h index 3a3340b..222e32e 100644 --- a/Source/Blaster/Weapon/Weapon.h +++ b/Source/Blaster/Weapon/Weapon.h @@ -144,4 +144,13 @@ public: FORCEINLINE int32 GetMagCapacity() const { return MagCapacity; } bool IsEmpty(); bool IsFull(); + + // Convenience methods for WeaponType + FORCEINLINE bool IsPistol() const { return WeaponType == EWeaponType::EWT_Pistol; } + FORCEINLINE bool IsSMG() const { return WeaponType == EWeaponType::EWT_SubmachineGun; } + FORCEINLINE bool IsAR() const { return WeaponType == EWeaponType::EWT_AssaultRifle; } + FORCEINLINE bool IsShotgun() const { return WeaponType == EWeaponType::EWT_Shotgun; } + FORCEINLINE bool IsGrenadeLauncher() const { return WeaponType == EWeaponType::EWT_GrenadeLauncher; } + FORCEINLINE bool IsRocketLauncher() const { return WeaponType == EWeaponType::EWT_RocketLauncher; } + FORCEINLINE bool IsSniper() const { return WeaponType == EWeaponType::EWT_SniperRifle; } };