ExoWest/Source/Exo/Private/Characters/Components/ShootingComponent.cpp

176 lines
5.3 KiB
C++
Raw Blame History

// Fill out your copyright notice in the Description page of Project Settings.
#include "Characters/Components/ShootingComponent.h"
#include "KismetTraceUtils.h"
// 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();
PlayerCharacter = Cast<AExoPlayerCharacter>(GetOwner());
}
void UShootingComponent::Shoot()
{
if (!bIsHoldingGun || CurrentAmmo == 0 || bIsReloading || !bCanShoot) return;
APawn* PawnOwner = Cast<APawn>(PlayerCharacter);
if (!PawnOwner || !PawnOwner->GetController()) return;
bCanShoot = false;
CurrentAmmo--;
FVector ViewLocation;
FRotator ViewRotation;
PawnOwner->GetController()->GetPlayerViewPoint(ViewLocation, ViewRotation);
FVector ForwardVector = ViewRotation.Vector();
FVector LineStart = ViewLocation; //PlayerCharacter->GetActorLocation();
FVector LineEnd = LineStart + (ForwardVector * MaxRange);
FHitResult HitResult;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(PlayerCharacter);
// Strza<7A>
bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, LineStart, LineEnd, ECC_Visibility, QueryParams);
if (bHit && HitResult.GetActor() && HitResult.GetActor()->Implements<UDamageable>())
{
IDamageable::Execute_TakeDamage(HitResult.GetActor(), FireDamageValue);
UE_LOG(LogTemp, Display, TEXT("Shoot. Ammo: %d/%d"), CurrentAmmo, MaxAmmo); // Docelowo tutaj wywo<77>anie UI aktualizuj<75>ce stan ammo
}
PlayerCharacter->GetWorldTimerManager().SetTimer(ShootCooldownTimer, this, &UShootingComponent::ResetFireCooldown, FireRateCooldown, false);
// Odrzut
float RecoilPitch = FMath::RandRange(-1.0f, -0.5f);
float RecoilYaw = FMath::RandRange(-0.5f, 0.5f);
PlayerCharacter->AddControllerPitchInput(RecoilPitch * RecoilForceMultiplier);
PlayerCharacter->AddControllerYawInput(RecoilYaw * RecoilForceMultiplier);
// DEBUG
if (bShowDebugLine)
DrawDebugLine(GetWorld(), LineStart, LineEnd, FColor::Red, false, 1.0f, 0, 1.0f);
}
void UShootingComponent::MeleAttack()
{
FVector ForwardVector = PlayerCharacter->GetActorForwardVector();
FVector ViewLocation;
FRotator ViewRotation;
PlayerCharacter->GetController()->GetPlayerViewPoint(ViewLocation, ViewRotation);
FVector EndVector = ViewLocation + ForwardVector * MeleRange;
FHitResult Hit;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(PlayerCharacter);
//DrawDebugLine(GetWorld(), ViewLocation, EndVector, FColor::Red, false, 1.0f, 0, 1.0f);
if (GetWorld()->LineTraceSingleByChannel(Hit, ViewLocation, EndVector, ECC_Visibility, QueryParams))
{
if (Hit.GetActor()->Implements<UDamageable>())
{
IDamageable::Execute_TakeDamage(Hit.GetActor(), MeleDamageValue);
}
}
}
void UShootingComponent::Reload()
{
if (!bIsHoldingGun || bIsReloading) return;
bIsReloading = true;
CurrentAmmo = MaxAmmo;
PlayerCharacter->GetWorldTimerManager().SetTimer(ReloadTimer, this, &UShootingComponent::ReloadCompleted, ReloadTime, false);
UE_LOG(LogTemp, Display, TEXT("Reloaded. Ammo: %d/%d"), CurrentAmmo, MaxAmmo); // Docelowo tutaj wywo<77>anie UI aktualizuj<75>ce stan ammo
}
void UShootingComponent::PickUpGun(AGunBase* gunItem)
{
if (bIsHoldingGun)
DropGun();
bIsHoldingGun = true;
HoldingGunClass = gunItem->GetClass();
MaxRange = gunItem->MaxRange;
FireDamageValue = gunItem->DamageValue;
FireRateCooldown = gunItem->FireRateCooldown;
RecoilForceMultiplier = gunItem->RecoilForceMultiplier;
ReloadTime = gunItem->ReloadTime;
CurrentAmmo = gunItem->CurrentAmmo;
MaxAmmo = gunItem->MaxAmmo;
}
void UShootingComponent::DropGun()
{
if (!bIsHoldingGun) return;
FVector ForwardVector = PlayerCharacter->GetActorForwardVector();
FVector PlayerPos = PlayerCharacter->GetActorLocation();
FVector DroppedGunPos = PlayerPos + (ForwardVector * DropGunRange);
FTransform DroppedGunTransform = PlayerCharacter->GetActorTransform();
DroppedGunTransform.SetLocation(DroppedGunPos);
AGunBase* DroppedGun = GetWorld()->SpawnActor<AGunBase>(HoldingGunClass, DroppedGunTransform);
if (DroppedGun)
{
DroppedGun->MaxRange = MaxRange;
DroppedGun->DamageValue = FireDamageValue;
DroppedGun->FireRateCooldown = FireRateCooldown;
DroppedGun->RecoilForceMultiplier = RecoilForceMultiplier;
DroppedGun->ReloadTime = ReloadTime;
DroppedGun->CurrentAmmo = CurrentAmmo;
DroppedGun->MaxAmmo = MaxAmmo;
bIsHoldingGun = false;
}
}
void UShootingComponent::ResetFireCooldown()
{
bCanShoot = true;
}
void UShootingComponent::ReloadCompleted()
{
bIsReloading = false;
}
// Called every frame
void UShootingComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}