175 - Shotgun Fire RPCs

This commit is contained in:
Kingsmedia 2022-05-26 15:06:27 +02:00
parent 82e10b18a6
commit 07fb4c4e5b
10 changed files with 73 additions and 49 deletions

Binary file not shown.

View File

@ -125,32 +125,34 @@ void UCombatComponent::Fire()
void UCombatComponent::FireProjectileWeapon() void UCombatComponent::FireProjectileWeapon()
{ {
if (PrimaryWeapon) if (PrimaryWeapon && Character)
{ {
HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget; HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
LocalFire(HitTarget); if (!Character->HasAuthority()) LocalFire(HitTarget);
ServerFire(HitTarget); ServerFire(HitTarget);
} }
} }
void UCombatComponent::FireHitScanWeapon() void UCombatComponent::FireHitScanWeapon()
{ {
if (PrimaryWeapon) if (PrimaryWeapon && Character)
{ {
HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget; HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
LocalFire(HitTarget); if (!Character->HasAuthority()) LocalFire(HitTarget);
ServerFire(HitTarget); ServerFire(HitTarget);
} }
} }
void UCombatComponent::FireShotgun() void UCombatComponent::FireShotgun()
{ {
if (AShotgun* Shotgun = Cast<AShotgun>(PrimaryWeapon)) AShotgun* Shotgun = Cast<AShotgun>(PrimaryWeapon);
if (Shotgun && Character)
{ {
TArray<FVector> HitTargets; TArray<FVector_NetQuantize> HitTargets;
Shotgun->ShotgunTraceEndWithScatter(HitTarget, HitTargets); Shotgun->ShotgunTraceEndWithScatter(HitTarget, HitTargets);
if (!Character->HasAuthority()) ShotgunLocalFire(HitTargets);
ServerShotgunFire(HitTargets);
} }
} }
void UCombatComponent::StartFireTimer() void UCombatComponent::StartFireTimer()
@ -186,16 +188,20 @@ void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& T
LocalFire(TraceHitTarget); LocalFire(TraceHitTarget);
} }
void UCombatComponent::ServerShotgunFire_Implementation(const TArray<FVector_NetQuantize>& TraceHitTargets)
{
MulticastShotgunFire(TraceHitTargets);
}
void UCombatComponent::MulticastShotgunFire_Implementation(const TArray<FVector_NetQuantize>& TraceHitTargets)
{
if (Character && Character->IsLocallyControlled() && !Character->HasAuthority()) return;
ShotgunLocalFire(TraceHitTargets);
}
void UCombatComponent::LocalFire(const FVector_NetQuantize& TraceHitTarget) void UCombatComponent::LocalFire(const FVector_NetQuantize& TraceHitTarget)
{ {
if (PrimaryWeapon == nullptr) return; if (PrimaryWeapon == nullptr) return;
if (Character && CombatState == ECombatState::ECS_Reloading && PrimaryWeapon->IsShotgun())
{
Character->PlayFireMontage(bAiming);
PrimaryWeapon->Fire(TraceHitTarget);
CombatState = ECombatState::ECS_Unoccupied;
return;
}
if (Character && CombatState == ECombatState::ECS_Unoccupied) if (Character && CombatState == ECombatState::ECS_Unoccupied)
{ {
Character->PlayFireMontage(bAiming); Character->PlayFireMontage(bAiming);
@ -203,6 +209,18 @@ void UCombatComponent::LocalFire(const FVector_NetQuantize& TraceHitTarget)
} }
} }
void UCombatComponent::ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets)
{
AShotgun* Shotgun = Cast<AShotgun>(PrimaryWeapon);
if (Shotgun == nullptr || Character == nullptr) return;
if (CombatState == ECombatState::ECS_Reloading || CombatState == ECombatState::ECS_Unoccupied)
{
Character->PlayFireMontage(bAiming);
Shotgun->FireShotgun(TraceHitTargets);
CombatState = ECombatState::ECS_Unoccupied;
}
}
void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip) void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip)
{ {
if (Character == nullptr || WeaponToEquip == nullptr) return; if (Character == nullptr || WeaponToEquip == nullptr) return;

View File

@ -70,6 +70,12 @@ protected:
UFUNCTION(NetMulticast, Reliable) UFUNCTION(NetMulticast, Reliable)
void MulticastFire(const FVector_NetQuantize& TraceHitTarget); void MulticastFire(const FVector_NetQuantize& TraceHitTarget);
UFUNCTION(Server, Reliable)
void ServerShotgunFire(const TArray<FVector_NetQuantize>& TraceHitTargets);
UFUNCTION(NetMulticast, Reliable)
void MulticastShotgunFire(const TArray<FVector_NetQuantize>& TraceHitTargets);
void TraceUnderCrosshairs(FHitResult& TraceHitResult); void TraceUnderCrosshairs(FHitResult& TraceHitResult);
void SetHUDCrosshairs(float DeltaTime); void SetHUDCrosshairs(float DeltaTime);
@ -156,6 +162,7 @@ private:
void StartFireTimer(); void StartFireTimer();
void FireTimerFinished(); void FireTimerFinished();
void LocalFire(const FVector_NetQuantize& TraceHitTarget); void LocalFire(const FVector_NetQuantize& TraceHitTarget);
void ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets);
bool CanFire(); bool CanFire();

View File

@ -8,28 +8,29 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h" #include "Kismet/KismetMathLibrary.h"
void AShotgun::Fire(const FVector& HitTarget) void AShotgun::FireShotgun(const TArray<FVector_NetQuantize>& HitTargets)
{ {
AWeapon::Fire(HitTarget); AWeapon::Fire(FVector());
const APawn* OwnerPawn = Cast<APawn>(GetOwner());
APawn* OwnerPawn = Cast<APawn>(GetOwner());
if (OwnerPawn == nullptr) return; if (OwnerPawn == nullptr) return;
AController* InstigatorController = OwnerPawn->GetController(); AController* InstigatorController = OwnerPawn->GetController();
const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash"); const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash");
if (MuzzleFlashSocket) if (MuzzleFlashSocket)
{ {
FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh()); const FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
FVector Start = SocketTransform.GetLocation(); const FVector Start = SocketTransform.GetLocation();
// Maps hit character to number of times hit
TMap<ABlasterCharacter*, uint32> HitMap; TMap<ABlasterCharacter*, uint32> HitMap;
for (uint32 i = 0; i < NumberOfPellets; i++)
for (FVector_NetQuantize HitTarget : HitTargets)
{ {
FHitResult FireHit; FHitResult FireHit;
WeaponTraceHit(Start, HitTarget, FireHit); WeaponTraceHit(Start, HitTarget, FireHit);
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor()); ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
if (BlasterCharacter && HasAuthority() && InstigatorController) if (BlasterCharacter)
{ {
if (HitMap.Contains(BlasterCharacter)) if (HitMap.Contains(BlasterCharacter))
{ {
@ -39,35 +40,34 @@ void AShotgun::Fire(const FVector& HitTarget)
{ {
HitMap.Emplace(BlasterCharacter, 1); HitMap.Emplace(BlasterCharacter, 1);
} }
} if (ImpactParticles)
if (ImpactParticles) {
{ UGameplayStatics::SpawnEmitterAtLocation(
UGameplayStatics::SpawnEmitterAtLocation( GetWorld(),
GetWorld(), ImpactParticles,
ImpactParticles, FireHit.ImpactPoint,
FireHit.ImpactPoint, FireHit.ImpactNormal.Rotation()
FireHit.ImpactNormal.Rotation() );
); }
} if (HitSound)
if (HitSound) {
{ UGameplayStatics::PlaySoundAtLocation(
UGameplayStatics::PlaySoundAtLocation( this,
this, HitSound,
HitSound, FireHit.ImpactPoint,
FireHit.ImpactPoint, .5f,
.5f, FMath::FRandRange(-.5f, .5f)
FMath::FRandRange(-.5f, .5f) );
); }
} }
} }
for (auto HitPair : HitMap) for (auto HitPair : HitMap)
{ {
if (HitPair.Key && HasAuthority() && InstigatorController) if (HitPair.Key && HasAuthority() && InstigatorController)
{ {
UGameplayStatics::ApplyDamage( UGameplayStatics::ApplyDamage(
HitPair.Key, HitPair.Key, // Character that was hit
Damage * HitPair.Value, Damage * HitPair.Value, // Multiply Damage by number of times hit
InstigatorController, InstigatorController,
this, this,
UDamageType::StaticClass() UDamageType::StaticClass()
@ -77,7 +77,7 @@ void AShotgun::Fire(const FVector& HitTarget)
} }
} }
void AShotgun::ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVector>& HitTargets) void AShotgun::ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVector_NetQuantize>& HitTargets)
{ {
const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash"); const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash");
if (MuzzleFlashSocket == nullptr) return; if (MuzzleFlashSocket == nullptr) return;
@ -94,7 +94,7 @@ void AShotgun::ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVect
const FVector RandVec = UKismetMathLibrary::RandomUnitVector() * FMath::FRandRange(0.f, SphereRadius); const FVector RandVec = UKismetMathLibrary::RandomUnitVector() * FMath::FRandRange(0.f, SphereRadius);
const FVector EndLoc = SphereCenter + RandVec; const FVector EndLoc = SphereCenter + RandVec;
FVector ToEndLoc = EndLoc - TraceStart; FVector ToEndLoc = EndLoc - TraceStart;
ToEndLoc = FVector(TraceStart + ToEndLoc * TRACE_LENGTH / ToEndLoc.Size()) ToEndLoc = FVector(TraceStart + ToEndLoc * TRACE_LENGTH / ToEndLoc.Size());
HitTargets.Add(ToEndLoc); HitTargets.Add(ToEndLoc);
} }

View File

@ -15,9 +15,8 @@ class BLASTER_API AShotgun : public AHitScanWeapon
GENERATED_BODY() GENERATED_BODY()
public: public:
virtual void FireShotgun(const TArray<FVector_NetQuantize>& HitTargets);
virtual void Fire(const FVector& HitTarget) override; void ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVector_NetQuantize>& HitTargets);
void ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVector>& HitTargets);
private: private: