// 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(GetOwner()); } void UShootingComponent::Shoot() { if (!bIsHoldingGun || CurrentAmmo == 0 || bIsReloading || !bCanShoot) return; APawn* PawnOwner = Cast(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� bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, LineStart, LineEnd, ECC_Visibility, QueryParams); if (bHit && HitResult.GetActor() && HitResult.GetActor()->Implements()) { IDamageable::Execute_TakeDamage(HitResult.GetActor(), FireDamageValue); UE_LOG(LogTemp, Display, TEXT("Shoot. Ammo: %d/%d"), CurrentAmmo, MaxAmmo); // Docelowo tutaj wywo�anie UI aktualizuj�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()) { 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�anie UI aktualizuj�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(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); // ... }