diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index f88c5dd..47b1890 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -438,7 +438,7 @@ void UCombatComponent::UpdateAmmoValues() { Controller->SetHUDCarriedAmmo(CarriedAmmo); } - PrimaryWeapon->AddAmmo(-ReloadAmount); + PrimaryWeapon->AddAmmo(ReloadAmount); } void UCombatComponent::UpdateShotgunAmmoValues() @@ -455,7 +455,7 @@ void UCombatComponent::UpdateShotgunAmmoValues() { Controller->SetHUDCarriedAmmo(CarriedAmmo); } - PrimaryWeapon->AddAmmo(-1); + PrimaryWeapon->AddAmmo(1); bCanFire = true; if (PrimaryWeapon->IsFull() || CarriedAmmo == 0) { diff --git a/Source/Blaster/Weapon/Weapon.cpp b/Source/Blaster/Weapon/Weapon.cpp index dbe9188..21c3eef 100644 --- a/Source/Blaster/Weapon/Weapon.cpp +++ b/Source/Blaster/Weapon/Weapon.cpp @@ -45,7 +45,6 @@ void AWeapon::GetLifetimeReplicatedProps(TArray& OutLifetimeP Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AWeapon, WeaponState); - DOREPLIFETIME(AWeapon, Ammo); } void AWeapon::EnableCustomDepth(bool bEnabled) @@ -131,15 +130,41 @@ void AWeapon::SpendRound() { Ammo = FMath::Clamp(Ammo - 1, 0, MagCapacity); SetHUDAmmo(); + if (HasAuthority()) + { + ClientUpdateAmmo(Ammo); + } + else + { + ++Sequence; + } } -void AWeapon::OnRep_Ammo() +void AWeapon::ClientUpdateAmmo_Implementation(int32 ServerAmmo) { + if (HasAuthority()) return; + Ammo = ServerAmmo; + --Sequence; + Ammo -= Sequence; + SetHUDAmmo(); +} + +void AWeapon::AddAmmo(int32 AmmoToAdd) +{ + Ammo = FMath::Clamp(Ammo + AmmoToAdd, 0, MagCapacity); + SetHUDAmmo(); + ClientAddAmmo(AmmoToAdd); +} + +void AWeapon::ClientAddAmmo_Implementation(int32 AmmoToAdd) +{ + if (HasAuthority()) return; + Ammo = FMath::Clamp(Ammo + AmmoToAdd, 0, MagCapacity); OwnerCharacter = OwnerCharacter == nullptr ? Cast(GetOwner()) : OwnerCharacter; if (OwnerCharacter && OwnerCharacter->GetCombat() && IsFull()) { OwnerCharacter->GetCombat()->JumpToShotgunEnd(); - } + } SetHUDAmmo(); } @@ -268,10 +293,7 @@ void AWeapon::Fire(const FVector& HitTarget) } } } - if (HasAuthority()) - { - SpendRound(); - } + SpendRound(); } void AWeapon::Dropped() @@ -288,12 +310,6 @@ void AWeapon::Dropped() OwnerController = nullptr; } -void AWeapon::AddAmmo(int32 Amount) -{ - Ammo = FMath::Clamp(Ammo - Amount, 0, MagCapacity); - SetHUDAmmo(); -} - FVector AWeapon::TraceEndWithScatter(const FVector& HitTarget) { const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash"); diff --git a/Source/Blaster/Weapon/Weapon.h b/Source/Blaster/Weapon/Weapon.h index 092c66e..0679316 100644 --- a/Source/Blaster/Weapon/Weapon.h +++ b/Source/Blaster/Weapon/Weapon.h @@ -41,7 +41,7 @@ public: void ShowPickupWidget(bool bShowWidget); virtual void Fire(const FVector& HitTarget); void Dropped(); - void AddAmmo(int32 Amount); + void AddAmmo(int32 AmmoToAdd); FVector TraceEndWithScatter(const FVector& HitTarget); // Textures for the weapon crosshairs @@ -146,17 +146,24 @@ private: UPROPERTY(EditAnywhere, Category = "Weapon Properties") TSubclassOf CasingClass; - UPROPERTY(EditAnywhere, ReplicatedUsing=OnRep_Ammo) + UPROPERTY(EditAnywhere) int32 Ammo; - UFUNCTION() - void OnRep_Ammo(); + UFUNCTION(Client, Reliable) // Server to Client RPC + void ClientUpdateAmmo(int32 ServerAmmo); + UFUNCTION(Client, Reliable) // Server to Client RPC + void ClientAddAmmo(int32 AmmoToAdd); + void SpendRound(); UPROPERTY(EditAnywhere) int32 MagCapacity; + // The number of unprocessed server requests for ammo + // Incremented in SpendRound(), decremented in ClientUpdateAmmo() + int32 Sequence = 0; + UPROPERTY() class ABlasterCharacter* OwnerCharacter;