175 - Shotgun Fire RPCs
This commit is contained in:
parent
82e10b18a6
commit
07fb4c4e5b
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue