blaster/Source/Blaster/Weapon/HitScanWeapon.cpp

136 lines
3.3 KiB
C++
Raw Normal View History

2022-05-19 17:13:21 +00:00
// Fill out your copyright notice in the Description page of Project Settings.
#include "HitScanWeapon.h"
#include "Blaster/Character/BlasterCharacter.h"
2022-05-27 16:36:56 +00:00
#include "Blaster/Components/LagCompensationComponent.h"
#include "Blaster/PlayerController/BlasterPlayerController.h"
2022-05-19 17:13:21 +00:00
#include "Engine/SkeletalMeshSocket.h"
#include "Kismet/GameplayStatics.h"
2022-05-19 17:35:20 +00:00
#include "Particles/ParticleSystemComponent.h"
2022-05-19 17:13:21 +00:00
void AHitScanWeapon::Fire(const FVector& HitTarget)
{
Super::Fire(HitTarget);
APawn* OwnerPawn = Cast<APawn>(GetOwner());
if (OwnerPawn == nullptr) return;
AController* InstigatorController = OwnerPawn->GetController();
const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash");
2022-05-19 17:35:20 +00:00
if (MuzzleFlashSocket)
2022-05-19 17:13:21 +00:00
{
FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
FVector Start = SocketTransform.GetLocation();
FHitResult FireHit;
2022-05-20 10:59:55 +00:00
WeaponTraceHit(Start, HitTarget, FireHit);
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
2022-05-29 09:59:15 +00:00
if (BlasterCharacter && InstigatorController)
2022-05-19 17:13:21 +00:00
{
2022-05-28 08:30:24 +00:00
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
if (HasAuthority() && bCauseAuthDamage)
2022-05-27 16:36:56 +00:00
{
2022-05-29 12:11:11 +00:00
const float DamageToCause = FireHit.BoneName.ToString() == FString("head") ? HeadShotDamage : Damage;
2022-05-27 16:36:56 +00:00
UGameplayStatics::ApplyDamage(
BlasterCharacter,
2022-05-29 12:11:11 +00:00
DamageToCause,
2022-05-27 16:36:56 +00:00
InstigatorController,
this,
UDamageType::StaticClass()
);
}
else if (!HasAuthority() && bUseServerSideRewind)
{
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(OwnerPawn) : OwnerCharacter;
OwnerController = OwnerController == nullptr ? Cast<ABlasterPlayerController>(InstigatorController) : OwnerController;
2022-05-27 19:57:52 +00:00
if (OwnerCharacter && OwnerController && OwnerCharacter->GetLagCompensation() && OwnerCharacter->IsLocallyControlled())
2022-05-27 16:36:56 +00:00
{
OwnerCharacter->GetLagCompensation()->ServerScoreRequest(
BlasterCharacter,
Start,
HitTarget,
OwnerController->GetServerTime() - OwnerController->SingleTripTime
2022-05-27 16:36:56 +00:00
);
}
}
2022-05-20 10:59:55 +00:00
}
if (ImpactParticles)
{
UGameplayStatics::SpawnEmitterAtLocation(
GetWorld(),
ImpactParticles,
FireHit.ImpactPoint,
FireHit.ImpactNormal.Rotation()
);
}
if (HitSound)
{
UGameplayStatics::PlaySoundAtLocation(
this,
HitSound,
FireHit.ImpactPoint
2022-05-19 17:13:21 +00:00
);
}
2022-05-19 18:51:50 +00:00
if (MuzzleFlash)
{
UGameplayStatics::SpawnEmitterAtLocation(
2022-05-20 10:59:55 +00:00
GetWorld(),
2022-05-19 18:51:50 +00:00
MuzzleFlash,
SocketTransform
);
}
if (FireSound)
{
UGameplayStatics::PlaySoundAtLocation(
this,
FireSound,
GetActorLocation()
);
}
2022-05-19 17:13:21 +00:00
}
}
2022-05-20 10:10:21 +00:00
2022-05-20 10:59:55 +00:00
void AHitScanWeapon::WeaponTraceHit(const FVector& TraceStart, const FVector& HitTarget, FHitResult& OutHit)
{
UWorld* World = GetWorld();
if (World)
{
2022-05-26 12:03:51 +00:00
FVector End = TraceStart + (HitTarget - TraceStart) * 1.25f;
2022-05-20 10:59:55 +00:00
World->LineTraceSingleByChannel(
OutHit,
TraceStart,
End,
ECC_Visibility
);
FVector BeamEnd = End;
if (OutHit.bBlockingHit)
{
BeamEnd = OutHit.ImpactPoint;
}
2022-05-29 12:11:11 +00:00
else
{
OutHit.ImpactPoint = End;
}
2022-05-26 12:03:51 +00:00
2022-05-20 10:59:55 +00:00
if (BeamParticles)
{
UParticleSystemComponent* Beam = UGameplayStatics::SpawnEmitterAtLocation(
World,
BeamParticles,
TraceStart,
FRotator::ZeroRotator,
true
);
if (Beam)
{
Beam->SetVectorParameter(FName("Target"), BeamEnd);
}
}
}
}