blaster/Source/Blaster/Weapon/Shotgun.cpp

128 lines
3.8 KiB
C++
Raw Normal View History

2022-05-20 10:10:21 +00:00
// Fill out your copyright notice in the Description page of Project Settings.
#include "Shotgun.h"
#include "Blaster/Character/BlasterCharacter.h"
2022-05-27 19:57:52 +00:00
#include "Blaster/Components/LagCompensationComponent.h"
#include "Blaster/PlayerController/BlasterPlayerController.h"
2022-05-20 10:10:21 +00:00
#include "Engine/SkeletalMeshSocket.h"
#include "Kismet/GameplayStatics.h"
2022-05-26 12:29:39 +00:00
#include "Kismet/KismetMathLibrary.h"
2022-05-20 10:10:21 +00:00
2022-05-26 13:06:27 +00:00
void AShotgun::FireShotgun(const TArray<FVector_NetQuantize>& HitTargets)
2022-05-20 10:10:21 +00:00
{
2022-05-26 13:06:27 +00:00
AWeapon::Fire(FVector());
2022-05-27 19:57:52 +00:00
APawn* OwnerPawn = Cast<APawn>(GetOwner());
2022-05-20 10:10:21 +00:00
if (OwnerPawn == nullptr) return;
AController* InstigatorController = OwnerPawn->GetController();
2022-05-20 10:59:55 +00:00
2022-05-20 10:10:21 +00:00
const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash");
if (MuzzleFlashSocket)
{
2022-05-26 13:06:27 +00:00
const FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
const FVector Start = SocketTransform.GetLocation();
2022-05-20 10:10:21 +00:00
2022-05-26 13:06:27 +00:00
// Maps hit character to number of times hit
2022-05-20 10:59:55 +00:00
TMap<ABlasterCharacter*, uint32> HitMap;
2022-05-26 13:06:27 +00:00
for (FVector_NetQuantize HitTarget : HitTargets)
2022-05-20 10:10:21 +00:00
{
2022-05-20 10:59:55 +00:00
FHitResult FireHit;
WeaponTraceHit(Start, HitTarget, FireHit);
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
2022-05-26 13:06:27 +00:00
if (BlasterCharacter)
2022-05-20 10:59:55 +00:00
{
if (HitMap.Contains(BlasterCharacter))
{
HitMap[BlasterCharacter]++;
}
else
{
HitMap.Emplace(BlasterCharacter, 1);
}
2022-05-26 13:06:27 +00:00
if (ImpactParticles)
{
UGameplayStatics::SpawnEmitterAtLocation(
GetWorld(),
ImpactParticles,
FireHit.ImpactPoint,
FireHit.ImpactNormal.Rotation()
);
}
if (HitSound)
{
UGameplayStatics::PlaySoundAtLocation(
this,
HitSound,
FireHit.ImpactPoint,
.5f,
FMath::FRandRange(-.5f, .5f)
);
}
2022-05-20 10:59:55 +00:00
}
}
2022-05-27 19:57:52 +00:00
TArray<ABlasterCharacter*> HitCharacters;
2022-05-20 10:59:55 +00:00
for (auto HitPair : HitMap)
{
2022-05-27 19:57:52 +00:00
if (HitPair.Key && InstigatorController)
{
2022-05-28 08:30:24 +00:00
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
if (HasAuthority() && bCauseAuthDamage)
2022-05-27 19:57:52 +00:00
{
UGameplayStatics::ApplyDamage(
HitPair.Key, // Character that was hit
Damage * HitPair.Value, // Multiply Damage by number of times hit
InstigatorController,
this,
UDamageType::StaticClass()
);
}
HitCharacters.Add(HitPair.Key);
}
}
if (!HasAuthority() && bUseServerSideRewind)
{
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(OwnerPawn) : OwnerCharacter;
OwnerController = OwnerController == nullptr ? Cast<ABlasterPlayerController>(InstigatorController) : OwnerController;
if (OwnerCharacter && OwnerController && OwnerCharacter->GetLagCompensation() && OwnerCharacter->IsLocallyControlled())
2022-05-20 10:59:55 +00:00
{
2022-05-27 19:57:52 +00:00
OwnerCharacter->GetLagCompensation()->ShotgunServerScoreRequest(
HitCharacters,
Start,
HitTargets,
OwnerController->GetServerTime() - OwnerController->SingleTripTime
2022-05-20 10:59:55 +00:00
);
}
2022-05-20 10:10:21 +00:00
}
}
}
2022-05-26 12:29:39 +00:00
2022-05-26 13:06:27 +00:00
void AShotgun::ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVector_NetQuantize>& HitTargets)
2022-05-26 12:29:39 +00:00
{
const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash");
if (MuzzleFlashSocket == nullptr) return;
const FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
const FVector TraceStart = SocketTransform.GetLocation();
const FVector ToTargetNormalized = (HitTarget - TraceStart).GetSafeNormal();
const FVector SphereCenter = TraceStart + ToTargetNormalized * DistanceToSphere;
for (uint32 i = 0; i < NumberOfPellets; i++)
{
const FVector RandVec = UKismetMathLibrary::RandomUnitVector() * FMath::FRandRange(0.f, SphereRadius);
const FVector EndLoc = SphereCenter + RandVec;
FVector ToEndLoc = EndLoc - TraceStart;
2022-05-26 13:06:27 +00:00
ToEndLoc = FVector(TraceStart + ToEndLoc * TRACE_LENGTH / ToEndLoc.Size());
2022-05-26 12:29:39 +00:00
HitTargets.Add(ToEndLoc);
}
}