// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Blaster/HUD/BlasterHUD.h" #include "Blaster/Types/CombatState.h" #include "Blaster/Weapon/WeaponTypes.h" #include "Components/ActorComponent.h" #include "Blaster/Weapon/Projectile.h" #include "CombatComponent.generated.h" UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class BLASTER_API UCombatComponent : public UActorComponent { GENERATED_BODY() public: UCombatComponent(); friend class ABlasterCharacter; virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; void EquipWeapon(class AWeapon* WeaponToEquip); void SwapWeapons(); void Reload(); void DropWeapons(); UFUNCTION(BlueprintCallable) void FinishedReloading(); void FireButtonPressed(bool bPressed); UFUNCTION(BlueprintCallable) void ShotgunShellReload(); void JumpToShotgunEnd(); UFUNCTION(BlueprintCallable) void ThrowGrenadeFinished(); UFUNCTION(BlueprintCallable) void LaunchGrenade(); UFUNCTION(Server, Reliable) void ServerLaunchGrenade(const FVector_NetQuantize& Target); void PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount); bool bLocallyReloading = false; protected: virtual void BeginPlay() override; void SetAiming(bool bIsAiming); UFUNCTION(Server, Reliable) void ServerSetAiming(bool bIsAiming); UFUNCTION() void OnRep_PrimaryWeapon(); UFUNCTION() void OnRep_SecondaryWeapon(); void Fire(); void FireProjectileWeapon(); void FireHitScanWeapon(); void FireShotgun(); UFUNCTION(Server, Reliable) void ServerFire(const FVector_NetQuantize& TraceHitTarget); UFUNCTION(NetMulticast, Reliable) void MulticastFire(const FVector_NetQuantize& TraceHitTarget); UFUNCTION(Server, Reliable) void ServerShotgunFire(const TArray& TraceHitTargets); UFUNCTION(NetMulticast, Reliable) void MulticastShotgunFire(const TArray& TraceHitTargets); void TraceUnderCrosshairs(FHitResult& TraceHitResult); void SetHUDCrosshairs(float DeltaTime); UFUNCTION(Server, Reliable) void ServerReload(); void HandleReload(); int32 AmountToReload(); void ThrowGrenade(); UFUNCTION(Server, Reliable) void ServerThrowGrenade(); UPROPERTY(EditAnywhere) TSubclassOf GrenadeClass; void DropPrimaryWeapon(); void AttachActorToRightHand(AActor* ActorToAttach); void AttachActorToLeftHand(AActor* ActorToAttach); void AttachActorToBackpack(AActor* ActorToAttach); void UpdateCarriedAmmo(); void PlayEquipWeaponSound(const AWeapon* Weapon); void ReloadEmptyWeapon(); void ShowAttachedGrenade(bool bShowGrenade); void EquipPrimaryWeapon(AWeapon* WeaponToEquip); void EquipSecondaryWeapon(AWeapon* WeaponToEquip); private: UPROPERTY() ABlasterCharacter* Character; UPROPERTY() class ABlasterPlayerController* Controller; UPROPERTY() ABlasterHUD* HUD; UPROPERTY(ReplicatedUsing=OnRep_PrimaryWeapon) AWeapon* PrimaryWeapon; UPROPERTY(ReplicatedUsing=OnRep_SecondaryWeapon) AWeapon* SecondaryWeapon; UPROPERTY(ReplicatedUsing = OnRep_Aiming) bool bAiming = false; bool bAimButtonPressed = false; UFUNCTION() void OnRep_Aiming(); UPROPERTY(EditAnywhere) float BaseWalkSpeed; UPROPERTY(EditAnywhere) float AimWalkSpeed; bool bFireButtonPressed; //HUD and Crosshairs float CrosshairVelocityFactor; float CrosshairInAirFactor; float CrosshairAimFactor; float CrosshairShootingFactor; FHUDPackage HUDPackage; // Aiming and FOV // Field of view when not aiming; set to the camera's base FOV in BeginPlay float DefaultFOV; UPROPERTY(EditAnywhere, Category = Combat) float ZoomedFOV = 30.f; float CurrentFOV; UPROPERTY(EditAnywhere, Category = Combat) float ZoomInterpSpeed = 20.f; void InterpFOV(float DeltaTime); FVector HitTarget; // Automatic fire FTimerHandle FireTimer; bool bCanFire = true; void StartFireTimer(); void FireTimerFinished(); void LocalFire(const FVector_NetQuantize& TraceHitTarget); void ShotgunLocalFire(const TArray& TraceHitTargets); bool CanFire(); // Carried ammo for the currently equipped weapon UPROPERTY(ReplicatedUsing=OnRep_CarriedAmmo) int32 CarriedAmmo; UFUNCTION() void OnRep_CarriedAmmo(); TMap CarriedAmmoMap; UPROPERTY(EditAnywhere) int32 MaxCarriedAmmo = 500; UPROPERTY(EditAnywhere) int32 StartingARAmmo = 30; UPROPERTY(EditAnywhere) int32 StartingRocketAmmo = 8; UPROPERTY(EditAnywhere) int32 StartingPistolAmmo = 15; UPROPERTY(EditAnywhere) int32 StartingSMGAmmo = 100; UPROPERTY(EditAnywhere) int32 StartingShotgunAmmo = 15; UPROPERTY(EditAnywhere) int32 StartingSniperAmmo = 15; UPROPERTY(EditAnywhere) int32 StartingGrenadeLauncherAmmo = 15; void InitializeCarriedAmmo(); UPROPERTY(ReplicatedUsing=OnRep_CombatState) ECombatState CombatState = ECombatState::ECS_Unoccupied; UFUNCTION() void OnRep_CombatState(); void UpdateAmmoValues(); void UpdateShotgunAmmoValues(); UPROPERTY(ReplicatedUsing = OnRep_Grenades) int32 Grenades = 4; UFUNCTION() void OnRep_Grenades(); UPROPERTY(EditAnywhere) int32 MaxGrenades = 4; void UpdateHUDGrenades(); public: FORCEINLINE int32 GetGrenades() const { return Grenades; } bool ShouldSwapWeapons(); };