diff --git a/Content/Blueprints/Weapon/BP_Pistol.uasset b/Content/Blueprints/Weapon/BP_Pistol.uasset index 257b821..006a154 100644 Binary files a/Content/Blueprints/Weapon/BP_Pistol.uasset and b/Content/Blueprints/Weapon/BP_Pistol.uasset differ diff --git a/Content/Blueprints/Weapon/BP_Shotgun.uasset b/Content/Blueprints/Weapon/BP_Shotgun.uasset index ee066db..9c6f552 100644 Binary files a/Content/Blueprints/Weapon/BP_Shotgun.uasset and b/Content/Blueprints/Weapon/BP_Shotgun.uasset differ diff --git a/Content/Maps/BlasterMap.umap b/Content/Maps/BlasterMap.umap index 4ffdb4d..f0b5b25 100644 Binary files a/Content/Maps/BlasterMap.umap and b/Content/Maps/BlasterMap.umap differ diff --git a/Source/Blaster/Weapon/HitScanWeapon.cpp b/Source/Blaster/Weapon/HitScanWeapon.cpp index 45706fb..6a41fd7 100644 --- a/Source/Blaster/Weapon/HitScanWeapon.cpp +++ b/Source/Blaster/Weapon/HitScanWeapon.cpp @@ -33,9 +33,11 @@ void AHitScanWeapon::Fire(const FVector& HitTarget) bool bCauseAuthDamage = !bUseServerSideRewind || OwnerPawn->IsLocallyControlled(); if (HasAuthority() && bCauseAuthDamage) { + const float DamageToCause = FireHit.BoneName.ToString() == FString("head") ? HeadShotDamage : Damage; + UGameplayStatics::ApplyDamage( BlasterCharacter, - Damage, + DamageToCause, InstigatorController, this, UDamageType::StaticClass() @@ -111,6 +113,10 @@ void AHitScanWeapon::WeaponTraceHit(const FVector& TraceStart, const FVector& Hi { BeamEnd = OutHit.ImpactPoint; } + else + { + OutHit.ImpactPoint = End; + } if (BeamParticles) { diff --git a/Source/Blaster/Weapon/Shotgun.cpp b/Source/Blaster/Weapon/Shotgun.cpp index b1a612a..306eba2 100644 --- a/Source/Blaster/Weapon/Shotgun.cpp +++ b/Source/Blaster/Weapon/Shotgun.cpp @@ -25,6 +25,7 @@ void AShotgun::FireShotgun(const TArray& HitTargets) // Maps hit character to number of times hit TMap HitMap; + TMap HeadShotHitMap; for (FVector_NetQuantize HitTarget : HitTargets) { @@ -34,14 +35,19 @@ void AShotgun::FireShotgun(const TArray& HitTargets) ABlasterCharacter* BlasterCharacter = Cast(FireHit.GetActor()); 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 { - HitMap.Emplace(BlasterCharacter, 1); + if (HitMap.Contains(BlasterCharacter)) HitMap[BlasterCharacter]++; + else HitMap.Emplace(BlasterCharacter, 1); } + if (ImpactParticles) { UGameplayStatics::SpawnEmitterAtLocation( @@ -65,23 +71,48 @@ void AShotgun::FireShotgun(const TArray& HitTargets) } TArray HitCharacters; + + // Maps Character hit to total damage + TMap DamageMap; + + // Calculate body shot damage by multiplying times hit x Damage - Stored in DamageMap 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(); if (HasAuthority() && bCauseAuthDamage) { UGameplayStatics::ApplyDamage( - HitPair.Key, // Character that was hit - Damage * HitPair.Value, // Multiply Damage by number of times hit + DamagePair.Key, // Character that was hit + DamagePair.Value, // Damage calculated in the two loops above InstigatorController, this, UDamageType::StaticClass() ); } - - HitCharacters.Add(HitPair.Key); } } diff --git a/Source/Blaster/Weapon/Weapon.h b/Source/Blaster/Weapon/Weapon.h index 61b83c9..09cbff2 100644 --- a/Source/Blaster/Weapon/Weapon.h +++ b/Source/Blaster/Weapon/Weapon.h @@ -127,6 +127,9 @@ protected: UPROPERTY(EditAnywhere) float Damage = 20.f; + UPROPERTY(EditAnywhere) + float HeadShotDamage = 40.f; + UPROPERTY(Replicated, EditAnywhere) bool bUseServerSideRewind = false; @@ -194,6 +197,7 @@ public: bool IsEmpty(); bool IsFull(); FORCEINLINE float GetDamage() const { return Damage; } + FORCEINLINE float GetHeadShotDamage() const { return HeadShotDamage; } // Convenience methods for WeaponType FORCEINLINE bool IsPistol() const { return WeaponType == EWeaponType::EWT_Pistol; }