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
// Sets default values for this component's properties
UShootingComponent : : UShootingComponent ( )
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick . bCanEverTick = true ;
// ...
}
// Called when the game starts
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-03-23 21:47:10 +01:00
if ( ! IsValid ( CurrentGun ) | | CurrentGun - > CurrentAmmo = = 0 | | bIsReloading | | ! bCanShoot ) return ;
2025-02-22 01:28:07 +01:00
bCanShoot = false ;
2025-03-23 21:47:10 +01:00
CurrentGun - > CurrentAmmo - - ;
2025-03-23 22:27:10 +01:00
AActor * HitActor = ExecuteLineTrace ( CurrentGun - > MaxRange ) ;
if ( HitActor )
2025-02-21 20:42:52 +01:00
{
2025-03-23 22:27:10 +01:00
IDamageable : : Execute_TakeDamage ( HitActor , CurrentGun - > DamageValue ) ;
2025-02-21 20:42:52 +01:00
2025-03-23 22:27:10 +01:00
UE_LOG ( LogTemp , Display , TEXT ( " Shoot. Ammo: %d/%d " ) , CurrentGun - > CurrentAmmo , CurrentGun - > MaxAmmo ) ; // Docelowo tutaj wywołanie UI aktualizujące stan ammo
2025-02-21 20:42:52 +01:00
}
2025-03-23 21:47:10 +01:00
PlayerCharacter - > GetWorldTimerManager ( ) . SetTimer ( ShootCooldownTimer , this , & UShootingComponent : : ResetFireCooldown , CurrentGun - > 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-03-23 21:47:10 +01:00
PlayerCharacter - > AddControllerPitchInput ( RecoilPitch * CurrentGun - > RecoilForceMultiplier ) ;
PlayerCharacter - > AddControllerYawInput ( RecoilYaw * CurrentGun - > 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-03-22 13:46:05 +01:00
{
FVector ForwardVector = PlayerCharacter - > GetActorForwardVector ( ) ;
FVector ViewLocation ;
FRotator ViewRotation ;
PlayerCharacter - > GetController ( ) - > GetPlayerViewPoint ( ViewLocation , ViewRotation ) ;
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-03-23 21:47:10 +01:00
if ( ! IsValid ( CurrentGun ) | | 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-03-23 21:47:10 +01:00
CurrentGun - > CurrentAmmo = CurrentGun - > MaxAmmo ;
PlayerCharacter - > GetWorldTimerManager ( ) . SetTimer ( ReloadTimer , this , & UShootingComponent : : ReloadCompleted , CurrentGun - > ReloadTime , false ) ;
2025-02-22 01:28:07 +01:00
2025-04-08 18:22:33 +02:00
UE_LOG ( LogTemp , Display , TEXT ( " Reloaded. Ammo: %d/%d " ) , CurrentGun - > CurrentAmmo , CurrentGun - > MaxAmmo ) ; // Docelowo tutaj wywo<77> anie UI aktualizuj<75> ce stan ammo
2025-02-22 01:28:07 +01:00
}
2025-03-15 20:17:03 +01:00
void UShootingComponent : : PickUpGun ( AGunBase * gunItem )
{
2025-03-23 21:47:10 +01:00
if ( IsValid ( CurrentGun ) & & IsValid ( SecondaryGun ) )
2025-03-15 20:17:03 +01:00
DropGun ( ) ;
2025-03-23 21:47:10 +01:00
AGunBase * NewGun = NewObject < AGunBase > ( ) ;
2025-03-15 20:17:03 +01:00
2025-03-23 21:47:10 +01:00
NewGun - > MaxRange = gunItem - > MaxRange ;
NewGun - > DamageValue = gunItem - > DamageValue ;
NewGun - > FireRateCooldown = gunItem - > FireRateCooldown ;
NewGun - > RecoilForceMultiplier = gunItem - > RecoilForceMultiplier ;
NewGun - > ReloadTime = gunItem - > ReloadTime ;
NewGun - > CurrentAmmo = gunItem - > CurrentAmmo ;
NewGun - > MaxAmmo = gunItem - > MaxAmmo ;
NewGun - > SceneItemClass = gunItem - > GetClass ( ) ;
if ( IsValid ( CurrentGun ) )
SecondaryGun = NewGun ;
else
CurrentGun = NewGun ;
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-03-23 21:47:10 +01:00
if ( ! IsValid ( CurrentGun ) ) return ;
2025-04-04 16:33:54 +02:00
StopAiming ( ) ;
2025-03-15 20:17:03 +01:00
2025-03-15 22:43:58 +01:00
FVector ForwardVector = PlayerCharacter - > GetActorForwardVector ( ) ;
FVector PlayerPos = PlayerCharacter - > GetActorLocation ( ) ;
FVector DroppedGunPos = PlayerPos + ( ForwardVector * DropGunRange ) ;
FTransform DroppedGunTransform = PlayerCharacter - > GetActorTransform ( ) ;
DroppedGunTransform . SetLocation ( DroppedGunPos ) ;
2025-03-15 20:17:03 +01:00
2025-03-23 21:47:10 +01:00
AGunBase * DroppedGun = GetWorld ( ) - > SpawnActor < AGunBase > ( CurrentGun - > SceneItemClass , DroppedGunTransform ) ;
2025-03-15 22:43:58 +01:00
if ( DroppedGun )
{
2025-03-23 21:47:10 +01:00
DroppedGun - > MaxRange = CurrentGun - > MaxRange ;
DroppedGun - > DamageValue = CurrentGun - > DamageValue ;
DroppedGun - > FireRateCooldown = CurrentGun - > FireRateCooldown ;
DroppedGun - > RecoilForceMultiplier = CurrentGun - > RecoilForceMultiplier ;
DroppedGun - > ReloadTime = CurrentGun - > ReloadTime ;
DroppedGun - > CurrentAmmo = CurrentGun - > CurrentAmmo ;
DroppedGun - > MaxAmmo = CurrentGun - > MaxAmmo ;
CurrentGun - > Destroy ( ) ;
CurrentGun = nullptr ;
2025-03-15 22:43:58 +01:00
}
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 ( )
{
AGunBase * temp = CurrentGun ;
CurrentGun = SecondaryGun ;
SecondaryGun = temp ;
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 ( )
{
if ( IsValid ( CurrentGun ) )
{
2025-04-04 19:53:32 +02:00
PlayerCharacter - > bIsAimingMode = true ;
PlayerCharacter - > GetCharacterMovement ( ) - > MaxWalkSpeed = PlayerCharacter - > WalkSpeed * AimingMoveSpeedScale ;
2025-04-04 16:33:54 +02:00
TargetFOV = CurrentGun - > AimingFOV ;
}
}
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-02-21 20:42:52 +01:00
// Called every frame
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
}