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 80d7cdb..5fb67a5 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/Content/Assets/MilitaryWeapSilver/Weapons/Animations/Fire_Shotgun_W.uasset b/Content/Assets/MilitaryWeapSilver/Weapons/Animations/Fire_Shotgun_W.uasset index 8ed6843..0a9e78d 100644 Binary files a/Content/Assets/MilitaryWeapSilver/Weapons/Animations/Fire_Shotgun_W.uasset and b/Content/Assets/MilitaryWeapSilver/Weapons/Animations/Fire_Shotgun_W.uasset differ diff --git a/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset b/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset index 4d9b2dd..b2e4f54 100644 Binary files a/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset and b/Content/Blueprints/Character/Animation/BlasterAnimBP.uasset differ diff --git a/Content/Blueprints/Character/Animation/Reload.uasset b/Content/Blueprints/Character/Animation/Reload.uasset index 22f1256..258e36d 100644 Binary files a/Content/Blueprints/Character/Animation/Reload.uasset and b/Content/Blueprints/Character/Animation/Reload.uasset differ diff --git a/Content/Blueprints/Character/BP_BlasterCharacter.uasset b/Content/Blueprints/Character/BP_BlasterCharacter.uasset index c6d0464..991dcba 100644 Binary files a/Content/Blueprints/Character/BP_BlasterCharacter.uasset and b/Content/Blueprints/Character/BP_BlasterCharacter.uasset differ diff --git a/Content/Blueprints/Weapon/BP_Shotgun.uasset b/Content/Blueprints/Weapon/BP_Shotgun.uasset index 54a43fa..f3cea60 100644 Binary files a/Content/Blueprints/Weapon/BP_Shotgun.uasset and b/Content/Blueprints/Weapon/BP_Shotgun.uasset differ diff --git a/Content/Maps/BlasterMap.umap b/Content/Maps/BlasterMap.umap index 040f129..51029f1 100644 Binary files a/Content/Maps/BlasterMap.umap and b/Content/Maps/BlasterMap.umap differ diff --git a/Source/Blaster/Character/BlasterCharacter.h b/Source/Blaster/Character/BlasterCharacter.h index ddebdce..05ddd5a 100644 --- a/Source/Blaster/Character/BlasterCharacter.h +++ b/Source/Blaster/Character/BlasterCharacter.h @@ -196,4 +196,5 @@ public: ECombatState GetCombatState() const; FORCEINLINE UCombatComponent* GetCombat() const { return Combat; } FORCEINLINE bool GetDisableGameplay() const { return bDisableGameplay; } + FORCEINLINE UAnimMontage* GetReloadMontage() const { return ReloadMontage; } }; diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index f0e0813..cdf60b1 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -74,6 +74,14 @@ void UCombatComponent::FireButtonPressed(bool bPressed) } } +void UCombatComponent::ShotgunShellReload() +{ + if (Character && Character->HasAuthority()) + { + UpdateShotgunAmmoValues(); + } +} + void UCombatComponent::Fire() { if (CanFire()) @@ -121,6 +129,13 @@ 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) + { + Character->PlayFireMontage(bAiming); + EquippedWeapon->Fire(TraceHitTarget); + CombatState = ECombatState::ECS_Unoccupied; + return; + } if (Character && CombatState == ECombatState::ECS_Unoccupied) { Character->PlayFireMontage(bAiming); @@ -188,7 +203,7 @@ void UCombatComponent::ServerReload_Implementation() // return if weapon mag is at max capacity if (EquippedWeapon->GetAmmo() == EquippedWeapon->GetMagCapacity()) return; - + CombatState = ECombatState::ECS_Reloading; HandleReload(); } @@ -224,6 +239,38 @@ void UCombatComponent::UpdateAmmoValues() EquippedWeapon->AddAmmo(-ReloadAmount); } +void UCombatComponent::UpdateShotgunAmmoValues() +{ + if (Character == nullptr || EquippedWeapon == nullptr) return; + + if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType())) + { + CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= 1; + CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()]; + } + Controller = Controller == nullptr ? Cast(Character->Controller) : Controller; + if (Controller) + { + Controller->SetHUDCarriedAmmo(CarriedAmmo); + } + EquippedWeapon->AddAmmo(-1); + bCanFire = true; + if (EquippedWeapon->IsFull() || CarriedAmmo == 0) + { + JumpToShotgunEnd(); + } +} + +void UCombatComponent::JumpToShotgunEnd() +{ + // Jump to ShotgunEnd section + UAnimInstance* AnimInstance = Character->GetMesh()->GetAnimInstance(); + if (AnimInstance && Character->GetReloadMontage()) + { + AnimInstance->Montage_JumpToSection(FName("ShotgunEnd")); + } +} + void UCombatComponent::OnRep_CombatState() { switch (CombatState) @@ -425,7 +472,7 @@ void UCombatComponent::SetAiming(bool bIsAiming) ServerSetAiming(bIsAiming); Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed; - + if (Character->IsLocallyControlled() && EquippedWeapon->GetWeaponType() == EWeaponType::EWT_SniperRifle) { Character->ShowSniperScopeWidget(bIsAiming); @@ -444,7 +491,10 @@ void UCombatComponent::ServerSetAiming_Implementation(bool bIsAiming) bool UCombatComponent::CanFire() { if (EquippedWeapon == nullptr) return false; - return !EquippedWeapon->IsEmpty() && bCanFire && CombatState == ECombatState::ECS_Unoccupied; + if (EquippedWeapon->IsEmpty()) return false; + if (!bCanFire) return false; + if (CombatState == ECombatState::ECS_Reloading && EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true; + return CombatState == ECombatState::ECS_Unoccupied; } void UCombatComponent::OnRep_CarriedAmmo() @@ -454,6 +504,15 @@ void UCombatComponent::OnRep_CarriedAmmo() { Controller->SetHUDCarriedAmmo(CarriedAmmo); } + bool bJumpToShotgunEnd = CombatState == ECombatState::ECS_Reloading && + EquippedWeapon != nullptr && + EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun && + CarriedAmmo == 0; + + if (bJumpToShotgunEnd) + { + JumpToShotgunEnd(); + } } void UCombatComponent::InitializeCarriedAmmo() diff --git a/Source/Blaster/Components/CombatComponent.h b/Source/Blaster/Components/CombatComponent.h index cc4ee43..5ba9639 100644 --- a/Source/Blaster/Components/CombatComponent.h +++ b/Source/Blaster/Components/CombatComponent.h @@ -25,9 +25,14 @@ public: void Reload(); UFUNCTION(BlueprintCallable) void FinishedReloading(); - void UpdateAmmoValues(); void FireButtonPressed(bool bPressed); + + UFUNCTION(BlueprintCallable) + void ShotgunShellReload(); + + void JumpToShotgunEnd(); + protected: virtual void BeginPlay() override; void SetAiming(bool bIsAiming); @@ -146,4 +151,7 @@ private: UFUNCTION() void OnRep_CombatState(); + + void UpdateAmmoValues(); + void UpdateShotgunAmmoValues(); }; diff --git a/Source/Blaster/Weapon/Weapon.cpp b/Source/Blaster/Weapon/Weapon.cpp index 6947cf0..6afba49 100644 --- a/Source/Blaster/Weapon/Weapon.cpp +++ b/Source/Blaster/Weapon/Weapon.cpp @@ -5,6 +5,7 @@ #include "Casing.h" #include "Blaster/Character/BlasterCharacter.h" +#include "Blaster/Components/CombatComponent.h" #include "Blaster/PlayerController/BlasterPlayerController.h" #include "Components/SphereComponent.h" #include "Components/WidgetComponent.h" @@ -119,6 +120,11 @@ void AWeapon::SpendRound() void AWeapon::OnRep_Ammo() { + OwnerCharacter = OwnerCharacter == nullptr ? Cast(GetOwner()) : OwnerCharacter; + if (OwnerCharacter && OwnerCharacter->GetCombat() && IsFull()) + { + OwnerCharacter->GetCombat()->JumpToShotgunEnd(); + } SetHUDAmmo(); } @@ -160,6 +166,11 @@ bool AWeapon::IsEmpty() return Ammo <= 0; } +bool AWeapon::IsFull() +{ + return Ammo == MagCapacity; +} + void AWeapon::OnRep_WeaponState() { switch (WeaponState) diff --git a/Source/Blaster/Weapon/Weapon.h b/Source/Blaster/Weapon/Weapon.h index c136ddc..2896d49 100644 --- a/Source/Blaster/Weapon/Weapon.h +++ b/Source/Blaster/Weapon/Weapon.h @@ -140,4 +140,5 @@ public: FORCEINLINE int32 GetAmmo() const { return Ammo; } FORCEINLINE int32 GetMagCapacity() const { return MagCapacity; } bool IsEmpty(); + bool IsFull(); };