diff --git a/Content/Blueprints/HUD/WBP_CharacterOverlay.uasset b/Content/Blueprints/HUD/WBP_CharacterOverlay.uasset index 514fc0a..b31c20a 100644 Binary files a/Content/Blueprints/HUD/WBP_CharacterOverlay.uasset and b/Content/Blueprints/HUD/WBP_CharacterOverlay.uasset differ diff --git a/Content/Blueprints/Weapon/BP_AssaultRifle.uasset b/Content/Blueprints/Weapon/BP_AssaultRifle.uasset index fad8d43..4189f77 100644 Binary files a/Content/Blueprints/Weapon/BP_AssaultRifle.uasset and b/Content/Blueprints/Weapon/BP_AssaultRifle.uasset differ diff --git a/Source/Blaster/Character/BlasterCharacter.cpp b/Source/Blaster/Character/BlasterCharacter.cpp index c30ceca..5f82e86 100644 --- a/Source/Blaster/Character/BlasterCharacter.cpp +++ b/Source/Blaster/Character/BlasterCharacter.cpp @@ -137,6 +137,10 @@ void ABlasterCharacter::Eliminated() void ABlasterCharacter::MulticastEliminated_Implementation() { + if (BlasterPlayerController) + { + BlasterPlayerController->SetHUDWeaponAmmo(0); + } bEliminated = true; PlayEliminatedMontage(); diff --git a/Source/Blaster/Components/CombatComponent.cpp b/Source/Blaster/Components/CombatComponent.cpp index 9780d79..608c848 100644 --- a/Source/Blaster/Components/CombatComponent.cpp +++ b/Source/Blaster/Components/CombatComponent.cpp @@ -274,7 +274,10 @@ void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult) void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) { if (Character == nullptr || WeaponToEquip == nullptr) return; - + if (EquippedWeapon) + { + EquippedWeapon->Dropped(); + } EquippedWeapon = WeaponToEquip; EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped); const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket")); @@ -283,6 +286,7 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) HandSocket->AttachActor(EquippedWeapon, Character->GetMesh()); } EquippedWeapon->SetOwner(Character); + EquippedWeapon->SetHUDAmmo(); Character->GetCharacterMovement()->bOrientRotationToMovement = false; Character->bUseControllerRotationYaw = true; } diff --git a/Source/Blaster/HUD/CharacterOverlay.h b/Source/Blaster/HUD/CharacterOverlay.h index b8094b4..e996edf 100644 --- a/Source/Blaster/HUD/CharacterOverlay.h +++ b/Source/Blaster/HUD/CharacterOverlay.h @@ -28,4 +28,7 @@ public: UPROPERTY(meta = (BindWidget)) UTextBlock* DefeatsValue; + UPROPERTY(meta = (BindWidget)) + UTextBlock* WeaponAmmoValue; + }; diff --git a/Source/Blaster/PlayerController/BlasterPlayerController.cpp b/Source/Blaster/PlayerController/BlasterPlayerController.cpp index d75ce2d..ada3f41 100644 --- a/Source/Blaster/PlayerController/BlasterPlayerController.cpp +++ b/Source/Blaster/PlayerController/BlasterPlayerController.cpp @@ -74,3 +74,18 @@ void ABlasterPlayerController::SetHUDDefeats(int32 Defeats) BlasterHUD->CharacterOverlay->DefeatsValue->SetText(FText::FromString(DefeatsAmount)); } } + +void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo) +{ + BlasterHUD = BlasterHUD == nullptr ? Cast(GetHUD()) : BlasterHUD; + bool bHUDValid = + BlasterHUD && + BlasterHUD->CharacterOverlay && + BlasterHUD->CharacterOverlay->WeaponAmmoValue; + + if (bHUDValid) + { + const FString WeaponAmmoAmount = FString::Printf(TEXT("%d"), Ammo); + BlasterHUD->CharacterOverlay->WeaponAmmoValue->SetText(FText::FromString(WeaponAmmoAmount)); + } +} diff --git a/Source/Blaster/PlayerController/BlasterPlayerController.h b/Source/Blaster/PlayerController/BlasterPlayerController.h index 1b95b0b..ace19be 100644 --- a/Source/Blaster/PlayerController/BlasterPlayerController.h +++ b/Source/Blaster/PlayerController/BlasterPlayerController.h @@ -19,6 +19,7 @@ public: void SetHUDHealth(float Health, float MaxHealth); void SetHUDScore(float Score); void SetHUDDefeats(int32 Defeats); + void SetHUDWeaponAmmo(int32 Ammo); virtual void OnPossess(APawn* InPawn) override; protected: diff --git a/Source/Blaster/Weapon/Weapon.cpp b/Source/Blaster/Weapon/Weapon.cpp index c88eee4..97d0364 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/PlayerController/BlasterPlayerController.h" #include "Components/SphereComponent.h" #include "Components/WidgetComponent.h" #include "Engine/SkeletalMeshSocket.h" @@ -37,6 +38,7 @@ void AWeapon::GetLifetimeReplicatedProps(TArray& OutLifetimeP Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AWeapon, WeaponState); + DOREPLIFETIME(AWeapon, Ammo); } void AWeapon::BeginPlay() @@ -81,6 +83,45 @@ void AWeapon::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActo } } + +void AWeapon::OnRep_Owner() +{ + Super::OnRep_Owner(); + if (Owner == nullptr) + { + OwnerCharacter = nullptr; + OwnerController = nullptr; + } else + { + SetHUDAmmo(); + } +} + +void AWeapon::SetHUDAmmo() +{ + OwnerCharacter = OwnerCharacter == nullptr ? Cast(GetOwner()) : OwnerCharacter; + if (OwnerCharacter) + { + OwnerController = OwnerController == nullptr ? Cast(OwnerCharacter->Controller) : OwnerController; + if (OwnerController) + { + OwnerController->SetHUDWeaponAmmo(Ammo); + } + } +} + +void AWeapon::SpendRound() +{ + --Ammo; + + SetHUDAmmo(); +} + +void AWeapon::OnRep_Ammo() +{ + SetHUDAmmo(); +} + void AWeapon::SetWeaponState(EWeaponState State) { WeaponState = State; @@ -155,6 +196,7 @@ void AWeapon::Fire(const FVector& HitTarget) } } } + SpendRound(); } void AWeapon::Dropped() @@ -163,4 +205,6 @@ void AWeapon::Dropped() const FDetachmentTransformRules DetachRules(EDetachmentRule::KeepWorld, true); WeaponMesh->DetachFromComponent(DetachRules); SetOwner(nullptr); + OwnerCharacter = nullptr; + OwnerController = nullptr; } diff --git a/Source/Blaster/Weapon/Weapon.h b/Source/Blaster/Weapon/Weapon.h index 1bf02e0..4f22af5 100644 --- a/Source/Blaster/Weapon/Weapon.h +++ b/Source/Blaster/Weapon/Weapon.h @@ -24,6 +24,8 @@ class BLASTER_API AWeapon : public AActor public: AWeapon(); virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; + virtual void OnRep_Owner() override; + void SetHUDAmmo(); void ShowPickupWidget(bool bShowWidget); virtual void Fire(const FVector& HitTarget); void Dropped(); @@ -102,7 +104,23 @@ private: UPROPERTY(EditAnywhere, Category= "Weapon Properties") TSubclassOf CasingClass; + + UPROPERTY(EditAnywhere, ReplicatedUsing=OnRep_Ammo) + int32 Ammo; + UFUNCTION() + void OnRep_Ammo(); + + void SpendRound(); + + UPROPERTY(EditAnywhere) + int32 MagCapacity; + + UPROPERTY() + class ABlasterCharacter* OwnerCharacter; + + UPROPERTY() + class ABlasterPlayerController* OwnerController; public: void SetWeaponState(EWeaponState State);