2025-02-21 20:42:52 +01:00
// Fill out your copyright notice in the Description page of Project Settings.
# include "Characters/Components/ShootingComponent.h"
2025-04-08 18:22:33 +02:00
# include "Items/ThrowableBase.h"
2025-02-21 20:42:52 +01:00
UShootingComponent : : UShootingComponent ( )
{
PrimaryComponentTick . bCanEverTick = true ;
}
void UShootingComponent : : BeginPlay ( )
{
Super : : BeginPlay ( ) ;
2025-02-22 01:28:07 +01:00
PlayerCharacter = Cast < AExoPlayerCharacter > ( GetOwner ( ) ) ;
2025-04-04 16:33:54 +02:00
CameraManager = GetWorld ( ) - > GetFirstPlayerController ( ) - > PlayerCameraManager ;
2025-02-21 20:42:52 +01:00
2025-04-04 16:33:54 +02:00
DefaultFOV = CameraManager - > GetFOVAngle ( ) ;
TargetFOV = DefaultFOV ;
}
2025-02-21 20:42:52 +01:00
void UShootingComponent : : Shoot ( )
{
2025-04-22 23:28:59 +02:00
if ( ! IsValid ( CurrentGunBase ) | | CurrentGunBase - > CurrentAmmo = = 0 | | bIsReloading | | ! bCanShoot ) return ;
2025-02-22 01:28:07 +01:00
bCanShoot = false ;
2025-04-22 23:28:59 +02:00
CurrentGunBase - > CurrentAmmo - - ;
2025-03-23 22:27:10 +01:00
2025-04-22 23:28:59 +02:00
AActor * HitActor = ExecuteLineTrace ( CurrentGunBase - > MaxRange ) ;
2025-03-23 22:27:10 +01:00
if ( HitActor )
2025-02-21 20:42:52 +01:00
{
2025-04-22 23:28:59 +02:00
IDamageable : : Execute_TakeDamage ( HitActor , CurrentGunBase - > DamageValue ) ;
2025-02-21 20:42:52 +01:00
2025-04-22 23:28:59 +02:00
UE_LOG ( LogTemp , Display , TEXT ( " Shoot. Ammo: %d/%d " ) , CurrentGunBase - > CurrentAmmo , CurrentGunBase - > MaxAmmo ) ; // Docelowo tutaj wywołanie UI aktualizujące stan ammo
2025-02-21 20:42:52 +01:00
}
2025-04-22 23:28:59 +02:00
PlayerCharacter - > GetWorldTimerManager ( ) . SetTimer ( ShootCooldownTimer , this , & UShootingComponent : : ResetFireCooldown , CurrentGunBase - > FireRateCooldown , false ) ;
2025-02-22 01:28:07 +01:00
// Odrzut
2025-02-22 20:33:07 +01:00
float RecoilPitch = FMath : : RandRange ( - 1.0f , - 0.5f ) ;
float RecoilYaw = FMath : : RandRange ( - 0.5f , 0.5f ) ;
2025-03-22 13:46:05 +01:00
2025-04-22 23:28:59 +02:00
PlayerCharacter - > AddControllerPitchInput ( RecoilPitch * CurrentGunBase - > RecoilForceMultiplier ) ;
PlayerCharacter - > AddControllerYawInput ( RecoilYaw * CurrentGunBase - > RecoilForceMultiplier ) ;
2025-02-21 20:42:52 +01:00
}
2025-03-22 13:46:05 +01:00
void UShootingComponent : : MeleAttack ( )
2025-03-23 22:27:10 +01:00
{
AActor * HitActor = ExecuteLineTrace ( MeleRange ) ;
if ( HitActor )
{
IDamageable : : Execute_TakeDamage ( HitActor , MeleDamageValue ) ;
}
}
AActor * UShootingComponent : : ExecuteLineTrace ( float LineRange )
2025-04-18 02:04:39 +02:00
{
FVector ForwardVector = CameraManager - > GetActorForwardVector ( ) ;
FVector ViewLocation = CameraManager - > GetCameraLocation ( ) ;
2025-03-22 13:46:05 +01:00
2025-03-23 22:27:10 +01:00
FVector EndVector = ViewLocation + ForwardVector * LineRange ;
2025-03-22 13:46:05 +01:00
FHitResult Hit ;
FCollisionQueryParams QueryParams ;
QueryParams . AddIgnoredActor ( PlayerCharacter ) ;
2025-03-23 22:27:10 +01:00
// DEBUG
2025-03-23 21:47:10 +01:00
if ( bShowDebugLine )
2025-04-16 22:12:16 +02:00
DrawDebugLine ( GetWorld ( ) , ViewLocation , EndVector , FColor : : Red , false , 5.0f , 0 , 1.0f ) ;
2025-03-22 13:46:05 +01:00
2025-03-23 22:27:10 +01:00
if ( GetWorld ( ) - > LineTraceSingleByChannel ( Hit , ViewLocation , EndVector , ECC_Visibility , QueryParams ) & &
IsValid ( Hit . GetActor ( ) ) & & Hit . GetActor ( ) - > Implements < UDamageable > ( ) )
2025-03-22 13:46:05 +01:00
{
2025-03-23 22:27:10 +01:00
return Hit . GetActor ( ) ;
2025-03-22 13:46:05 +01:00
}
2025-03-23 22:27:10 +01:00
return nullptr ;
2025-03-22 13:46:05 +01:00
}
2025-02-22 01:28:07 +01:00
void UShootingComponent : : Reload ( )
{
2025-04-22 23:28:59 +02:00
if ( ! IsValid ( CurrentGunBase ) | | bIsReloading ) return ;
2025-02-22 01:28:07 +01:00
bIsReloading = true ;
2025-04-04 16:33:54 +02:00
StopAiming ( ) ;
2025-02-22 01:28:07 +01:00
2025-04-22 23:28:59 +02:00
CurrentGunBase - > CurrentAmmo = CurrentGunBase - > MaxAmmo ;
PlayerCharacter - > GetWorldTimerManager ( ) . SetTimer ( ReloadTimer , this , & UShootingComponent : : ReloadCompleted , CurrentGunBase - > ReloadTime , false ) ;
2025-02-22 01:28:07 +01:00
2025-04-22 23:28:59 +02:00
UE_LOG ( LogTemp , Display , TEXT ( " Reloaded. Ammo: %d/%d " ) , CurrentGunBase - > CurrentAmmo , CurrentGunBase - > MaxAmmo ) ; // Docelowo tutaj wywo<77> anie UI aktualizuj<75> ce stan ammo
2025-02-22 01:28:07 +01:00
}
2025-04-18 01:53:08 +02:00
bool UShootingComponent : : AddAmmo ( EAmmoType CheckingAmmo , int AddValue )
{
// Adding ammo only if type is compatible
2025-05-15 16:43:25 +02:00
if ( CurrentGunBase & & CurrentGunBase - > AmmoType = = CheckingAmmo )
{
CurrentGunBase - > AddAmmo ( AddValue ) ;
return true ;
}
if ( SecondaryGunBase & & SecondaryGunBase - > AmmoType = = CheckingAmmo )
{
SecondaryGunBase - > AddAmmo ( AddValue ) ;
return true ;
2025-04-18 01:53:08 +02:00
}
return false ;
}
2025-04-22 23:28:59 +02:00
void UShootingComponent : : PickUpGun ( UStaticMeshComponent * PickedGunMesh )
2025-03-15 20:17:03 +01:00
{
2025-04-22 23:28:59 +02:00
if ( IsValid ( CurrentGunBase ) & & IsValid ( SecondaryGunBase ) )
2025-03-15 20:17:03 +01:00
DropGun ( ) ;
2025-04-22 23:28:59 +02:00
FAttachmentTransformRules AttachmentRules ( EAttachmentRule : : SnapToTarget , EAttachmentRule : : SnapToTarget ,
EAttachmentRule : : KeepRelative , true ) ;
PickedGunMesh - > SetSimulatePhysics ( false ) ;
PickedGunMesh - > SetCastShadow ( false ) ;
PickedGunMesh - > AttachToComponent ( PlayerCharacter - > Weapon , AttachmentRules , FName ( TEXT ( " GripPoint " ) ) ) ;
AGunBase * PickedGunBase = Cast < AGunBase > ( PickedGunMesh - > GetOwner ( ) ) ;
if ( IsValid ( CurrentGunBase ) )
{
SecondaryGunBase = PickedGunBase ;
SecondaryGunMesh = PickedGunMesh ;
SecondaryGunMesh - > SetVisibility ( false ) ;
}
2025-03-23 21:47:10 +01:00
else
2025-04-22 23:28:59 +02:00
{
CurrentGunBase = PickedGunBase ;
CurrentGunMesh = PickedGunMesh ;
}
2025-03-15 20:17:03 +01:00
}
2025-04-08 18:22:33 +02:00
bool UShootingComponent : : PickUpThrow ( AThrowableBase * ThrowItem )
{
AThrowableBase * NewThrowable = NewObject < AThrowableBase > ( ) ;
if ( IsValid ( ThrowableItem ) )
{
if ( ThrowableItem - > GetClass ( ) = = NewThrowable - > GetClass ( ) )
{
if ( ThrowableItem - > Quantity + ThrowItem - > Quantity > = ThrowableItem - > MaxQuantity )
{
ThrowableItem - > Quantity = ThrowableItem - > MaxQuantity ;
return false ;
}
ThrowableItem - > Quantity + = ThrowItem - > Quantity ;
return true ;
}
DropThrow ( ) ;
}
NewThrowable - > Damage = ThrowItem - > Damage ;
NewThrowable - > Quantity = ThrowItem - > Quantity ;
NewThrowable - > Radius = ThrowItem - > Radius ;
NewThrowable - > ThrowableType = ThrowItem - > ThrowableType ;
NewThrowable - > SceneItemClass = ThrowItem - > GetClass ( ) ;
ThrowableItem = NewThrowable ;
return true ;
}
2025-03-15 20:17:03 +01:00
void UShootingComponent : : DropGun ( )
{
2025-04-22 23:28:59 +02:00
if ( ! IsValid ( CurrentGunBase ) ) return ;
2025-04-04 16:33:54 +02:00
StopAiming ( ) ;
2025-03-15 20:17:03 +01:00
2025-04-22 23:28:59 +02:00
FDetachmentTransformRules DetachmentRules ( EDetachmentRule : : KeepRelative , EDetachmentRule : : KeepRelative ,
EDetachmentRule : : KeepRelative , false ) ;
2025-03-15 20:17:03 +01:00
2025-04-22 23:28:59 +02:00
CurrentGunMesh - > DetachFromComponent ( DetachmentRules ) ;
CurrentGunMesh - > SetSimulatePhysics ( true ) ;
CurrentGunMesh - > bCastDynamicShadow = true ;
CurrentGunMesh - > CastShadow = true ;
2025-03-15 22:43:58 +01:00
2025-04-22 23:28:59 +02:00
CurrentGunMesh = nullptr ;
CurrentGunBase = nullptr ;
2025-03-15 20:17:03 +01:00
}
2025-04-08 18:22:33 +02:00
void UShootingComponent : : DropThrow ( )
{
if ( ! IsValid ( ThrowableItem ) ) return ;
FVector ForwardVector = PlayerCharacter - > GetActorForwardVector ( ) ;
FVector DroppedPos = PlayerCharacter - > GetActorLocation ( ) + ( ForwardVector * 100.f ) ;
FTransform DroppedTransform = PlayerCharacter - > GetActorTransform ( ) ;
DroppedTransform . SetLocation ( DroppedPos ) ;
AThrowableBase * DropedItem = GetWorld ( ) - > SpawnActor < AThrowableBase > ( ThrowableItem - > SceneItemClass , DroppedTransform ) ;
if ( DropedItem )
{
ThrowableItem - > Quantity - - ;
DropedItem - > Damage = ThrowableItem - > Damage ;
DropedItem - > Radius = ThrowableItem - > Radius ;
DropedItem - > Quantity = ThrowableItem - > Quantity ;
DropedItem - > ThrowableType = ThrowableItem - > ThrowableType ;
}
}
2025-02-22 01:28:07 +01:00
void UShootingComponent : : ResetFireCooldown ( )
{
bCanShoot = true ;
}
void UShootingComponent : : ReloadCompleted ( )
{
bIsReloading = false ;
}
2025-02-21 20:42:52 +01:00
2025-03-23 21:47:10 +01:00
void UShootingComponent : : SelectGun ( bool bSelectFirstSlot )
{
if ( bSelectFirstSlot ! = bIsFirstGunSelected )
SwitchGun ( ) ;
}
void UShootingComponent : : SwitchGun ( )
{
2025-04-22 23:28:59 +02:00
AGunBase * tempBase = CurrentGunBase ;
CurrentGunBase = SecondaryGunBase ;
SecondaryGunBase = tempBase ;
UStaticMeshComponent * tempMesh = CurrentGunMesh ;
CurrentGunMesh = SecondaryGunMesh ;
SecondaryGunMesh = tempMesh ;
if ( IsValid ( SecondaryGunMesh ) )
SecondaryGunMesh - > SetVisibility ( false ) ;
if ( IsValid ( CurrentGunMesh ) )
CurrentGunMesh - > SetVisibility ( true ) ;
2025-03-23 21:47:10 +01:00
bIsFirstGunSelected = ! bIsFirstGunSelected ;
2025-04-04 16:33:54 +02:00
StopAiming ( ) ;
2025-03-23 21:47:10 +01:00
// Debug info
if ( bIsFirstGunSelected )
{
UE_LOG ( LogTemp , Display , TEXT ( " Zmiana broni na broń 1 " ) ) ;
}
else
{
UE_LOG ( LogTemp , Display , TEXT ( " Zmiana broni na broń 2 " ) ) ;
}
}
2025-04-04 16:33:54 +02:00
void UShootingComponent : : StartAiming ( )
{
2025-04-22 23:28:59 +02:00
if ( IsValid ( CurrentGunBase ) )
2025-04-04 16:33:54 +02:00
{
2025-04-04 19:53:32 +02:00
PlayerCharacter - > bIsAimingMode = true ;
PlayerCharacter - > GetCharacterMovement ( ) - > MaxWalkSpeed = PlayerCharacter - > WalkSpeed * AimingMoveSpeedScale ;
2025-04-22 23:28:59 +02:00
TargetFOV = CurrentGunBase - > AimingFOV ;
2025-04-04 16:33:54 +02:00
}
}
void UShootingComponent : : StopAiming ( )
{
2025-04-04 19:53:32 +02:00
PlayerCharacter - > bIsAimingMode = false ;
PlayerCharacter - > GetCharacterMovement ( ) - > MaxWalkSpeed = PlayerCharacter - > WalkSpeed ;
2025-04-04 16:33:54 +02:00
TargetFOV = DefaultFOV ;
}
2025-04-16 22:12:16 +02:00
void UShootingComponent : : Throw ( )
2025-04-08 18:22:33 +02:00
{
if ( IsValid ( ThrowableItem ) )
2025-04-16 22:12:16 +02:00
{
FVector DroppedPos = CameraManager - > GetCameraLocation ( ) + CameraManager - > GetActorForwardVector ( ) * 100.f ;
2025-04-08 18:22:33 +02:00
FTransform DroppedTransform = PlayerCharacter - > GetActorTransform ( ) ;
DroppedTransform . SetLocation ( DroppedPos ) ;
AThrowableBase * ThrowedItem = GetWorld ( ) - > SpawnActor < AThrowableBase > ( ThrowableItem - > SceneItemClass , DroppedTransform ) ;
if ( ThrowedItem )
{
ThrowableItem - > Quantity - - ;
ThrowedItem - > Damage = ThrowableItem - > Damage ;
ThrowedItem - > Radius = ThrowableItem - > Radius ;
ThrowedItem - > Quantity = 1 ;
ThrowedItem - > ThrowableType = ThrowableItem - > ThrowableType ;
FVector ThrowVector = ( ThrowedItem - > GetActorLocation ( ) - PlayerCharacter - > GetActorLocation ( ) ) . GetSafeNormal ( ) ;
2025-04-16 22:12:16 +02:00
ThrowedItem - > Mesh - > SetPhysicsLinearVelocity ( ThrowVector * 1000.f ) ; // Need force to change to the game
2025-04-08 18:22:33 +02:00
if ( ThrowableItem - > Quantity < = 0 )
{
ThrowableItem - > Destroy ( ) ;
ThrowableItem = nullptr ;
}
}
}
}
2025-04-22 23:28:59 +02:00
bool UShootingComponent : : IsHoldingGun ( )
{
if ( IsValid ( CurrentGunBase ) )
return true ;
return false ;
}
2025-02-21 20:42:52 +01:00
void UShootingComponent : : TickComponent ( float DeltaTime , ELevelTick TickType , FActorComponentTickFunction * ThisTickFunction )
{
Super : : TickComponent ( DeltaTime , TickType , ThisTickFunction ) ;
2025-04-04 16:33:54 +02:00
float CurrentFOV = CameraManager - > GetFOVAngle ( ) ;
2025-04-04 19:53:32 +02:00
float NewFOV = FMath : : FInterpTo ( CurrentFOV , TargetFOV , DeltaTime , AimingAnimationSpeed ) ;
2025-04-04 16:33:54 +02:00
CameraManager - > SetFOV ( NewFOV ) ;
2025-02-21 20:42:52 +01:00
}