211 - Head Shots
This commit is contained in:
parent
6f4c73273e
commit
0d5eb1b16d
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -33,9 +33,11 @@ void AHitScanWeapon::Fire(const FVector& HitTarget)
|
||||||
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
|
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
|
||||||
if (HasAuthority() && bCauseAuthDamage)
|
if (HasAuthority() && bCauseAuthDamage)
|
||||||
{
|
{
|
||||||
|
const float DamageToCause = FireHit.BoneName.ToString() == FString("head") ? HeadShotDamage : Damage;
|
||||||
|
|
||||||
UGameplayStatics::ApplyDamage(
|
UGameplayStatics::ApplyDamage(
|
||||||
BlasterCharacter,
|
BlasterCharacter,
|
||||||
Damage,
|
DamageToCause,
|
||||||
InstigatorController,
|
InstigatorController,
|
||||||
this,
|
this,
|
||||||
UDamageType::StaticClass()
|
UDamageType::StaticClass()
|
||||||
|
@ -111,6 +113,10 @@ void AHitScanWeapon::WeaponTraceHit(const FVector& TraceStart, const FVector& Hi
|
||||||
{
|
{
|
||||||
BeamEnd = OutHit.ImpactPoint;
|
BeamEnd = OutHit.ImpactPoint;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutHit.ImpactPoint = End;
|
||||||
|
}
|
||||||
|
|
||||||
if (BeamParticles)
|
if (BeamParticles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@ void AShotgun::FireShotgun(const TArray<FVector_NetQuantize>& HitTargets)
|
||||||
|
|
||||||
// Maps hit character to number of times hit
|
// Maps hit character to number of times hit
|
||||||
TMap<ABlasterCharacter*, uint32> HitMap;
|
TMap<ABlasterCharacter*, uint32> HitMap;
|
||||||
|
TMap<ABlasterCharacter*, uint32> HeadShotHitMap;
|
||||||
|
|
||||||
for (FVector_NetQuantize HitTarget : HitTargets)
|
for (FVector_NetQuantize HitTarget : HitTargets)
|
||||||
{
|
{
|
||||||
|
@ -34,14 +35,19 @@ void AShotgun::FireShotgun(const TArray<FVector_NetQuantize>& HitTargets)
|
||||||
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
|
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
|
||||||
if (BlasterCharacter)
|
if (BlasterCharacter)
|
||||||
{
|
{
|
||||||
if (HitMap.Contains(BlasterCharacter))
|
const bool bHeadShot = FireHit.BoneName.ToString() == FString("head");
|
||||||
|
|
||||||
|
if (bHeadShot)
|
||||||
{
|
{
|
||||||
HitMap[BlasterCharacter]++;
|
if (HeadShotHitMap.Contains(BlasterCharacter)) HeadShotHitMap[BlasterCharacter]++;
|
||||||
|
else HeadShotHitMap.Emplace(BlasterCharacter, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HitMap.Emplace(BlasterCharacter, 1);
|
if (HitMap.Contains(BlasterCharacter)) HitMap[BlasterCharacter]++;
|
||||||
|
else HitMap.Emplace(BlasterCharacter, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImpactParticles)
|
if (ImpactParticles)
|
||||||
{
|
{
|
||||||
UGameplayStatics::SpawnEmitterAtLocation(
|
UGameplayStatics::SpawnEmitterAtLocation(
|
||||||
|
@ -65,23 +71,48 @@ void AShotgun::FireShotgun(const TArray<FVector_NetQuantize>& HitTargets)
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<ABlasterCharacter*> HitCharacters;
|
TArray<ABlasterCharacter*> HitCharacters;
|
||||||
|
|
||||||
|
// Maps Character hit to total damage
|
||||||
|
TMap<ABlasterCharacter*, uint32> DamageMap;
|
||||||
|
|
||||||
|
// Calculate body shot damage by multiplying times hit x Damage - Stored in DamageMap
|
||||||
for (auto HitPair : HitMap)
|
for (auto HitPair : HitMap)
|
||||||
{
|
{
|
||||||
if (HitPair.Key && InstigatorController)
|
if (HitPair.Key)
|
||||||
|
{
|
||||||
|
DamageMap.Emplace(HitPair.Key, HitPair.Value * Damage);
|
||||||
|
|
||||||
|
HitCharacters.AddUnique(HitPair.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Calculate head shot damage by multiplying times hit x HeadShotDamage - Stored in DamageMap
|
||||||
|
for (auto HeadShotHitPair : HeadShotHitMap)
|
||||||
|
{
|
||||||
|
if (HeadShotHitPair.Key)
|
||||||
|
{
|
||||||
|
if (DamageMap.Contains(HeadShotHitPair.Key)) DamageMap[HeadShotHitPair.Key] += HeadShotHitPair.Value * HeadShotDamage;
|
||||||
|
else DamageMap.Emplace(HeadShotHitPair.Key, HeadShotHitPair.Value * HeadShotDamage);
|
||||||
|
|
||||||
|
HitCharacters.AddUnique(HeadShotHitPair.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop trough DamageMap to get total damage for each character
|
||||||
|
for (auto DamagePair : DamageMap)
|
||||||
|
{
|
||||||
|
if (DamagePair.Key && InstigatorController)
|
||||||
{
|
{
|
||||||
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
|
bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled();
|
||||||
if (HasAuthority() && bCauseAuthDamage)
|
if (HasAuthority() && bCauseAuthDamage)
|
||||||
{
|
{
|
||||||
UGameplayStatics::ApplyDamage(
|
UGameplayStatics::ApplyDamage(
|
||||||
HitPair.Key, // Character that was hit
|
DamagePair.Key, // Character that was hit
|
||||||
Damage * HitPair.Value, // Multiply Damage by number of times hit
|
DamagePair.Value, // Damage calculated in the two loops above
|
||||||
InstigatorController,
|
InstigatorController,
|
||||||
this,
|
this,
|
||||||
UDamageType::StaticClass()
|
UDamageType::StaticClass()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HitCharacters.Add(HitPair.Key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,9 @@ protected:
|
||||||
UPROPERTY(EditAnywhere)
|
UPROPERTY(EditAnywhere)
|
||||||
float Damage = 20.f;
|
float Damage = 20.f;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
float HeadShotDamage = 40.f;
|
||||||
|
|
||||||
UPROPERTY(Replicated, EditAnywhere)
|
UPROPERTY(Replicated, EditAnywhere)
|
||||||
bool bUseServerSideRewind = false;
|
bool bUseServerSideRewind = false;
|
||||||
|
|
||||||
|
@ -194,6 +197,7 @@ public:
|
||||||
bool IsEmpty();
|
bool IsEmpty();
|
||||||
bool IsFull();
|
bool IsFull();
|
||||||
FORCEINLINE float GetDamage() const { return Damage; }
|
FORCEINLINE float GetDamage() const { return Damage; }
|
||||||
|
FORCEINLINE float GetHeadShotDamage() const { return HeadShotDamage; }
|
||||||
|
|
||||||
// Convenience methods for WeaponType
|
// Convenience methods for WeaponType
|
||||||
FORCEINLINE bool IsPistol() const { return WeaponType == EWeaponType::EWT_Pistol; }
|
FORCEINLINE bool IsPistol() const { return WeaponType == EWeaponType::EWT_Pistol; }
|
||||||
|
|
Loading…
Reference in New Issue