More robust bullet impact sounds (#8325)
This commit is contained in:
@@ -33,7 +33,7 @@ namespace Content.Server.Weapon.Melee
|
||||
[Dependency] private readonly AdminLogSystem _logSystem = default!;
|
||||
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
|
||||
|
||||
private const float DamagePitchVariation = 0.15f;
|
||||
public const float DamagePitchVariation = 0.15f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -107,7 +107,7 @@ namespace Content.Server.Weapon.Melee
|
||||
$"{ToPrettyString(args.User):user} melee attacked {ToPrettyString(args.Target.Value):target} using {ToPrettyString(args.Used):used} and dealt {damageResult.Total:damage} damage");
|
||||
}
|
||||
|
||||
PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, comp.HitSound);
|
||||
PlayHitSound(target, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, comp.HitSound);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -165,7 +165,7 @@ namespace Content.Server.Weapon.Melee
|
||||
var target = entities.First();
|
||||
TryComp<MeleeWeaponComponent>(target, out var meleeWeapon);
|
||||
|
||||
PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, meleeWeapon?.HitSound);
|
||||
PlayHitSound(target, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, meleeWeapon?.HitSound);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -196,9 +196,9 @@ namespace Content.Server.Weapon.Melee
|
||||
RaiseLocalEvent(owner, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false);
|
||||
}
|
||||
|
||||
private string? GetHighestDamageSound(DamageSpecifier modifiedDamage)
|
||||
public static string? GetHighestDamageSound(DamageSpecifier modifiedDamage, IPrototypeManager protoManager)
|
||||
{
|
||||
var groups = modifiedDamage.GetDamagePerGroup(_protoManager);
|
||||
var groups = modifiedDamage.GetDamagePerGroup(protoManager);
|
||||
|
||||
// Use group if it's exclusive, otherwise fall back to type.
|
||||
if (groups.Count == 1)
|
||||
|
||||
@@ -3,12 +3,16 @@ using Content.Server.CombatMode;
|
||||
using Content.Server.Hands.Components;
|
||||
using Content.Server.Interaction.Components;
|
||||
using Content.Server.Projectiles.Components;
|
||||
using Content.Server.Weapon.Melee;
|
||||
using Content.Server.Weapon.Ranged.Ammunition.Components;
|
||||
using Content.Server.Weapon.Ranged.Barrels.Components;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Camera;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics;
|
||||
@@ -239,10 +243,12 @@ public sealed partial class GunSystem
|
||||
var result = rayCastResults[0];
|
||||
var distance = result.Distance;
|
||||
hitscan.FireEffects(shooter, distance, angle, result.HitEntity);
|
||||
var dmg = _damageable.TryChangeDamage(result.HitEntity, hitscan.Damage);
|
||||
if (dmg != null)
|
||||
var modifiedDamage = _damageable.TryChangeDamage(result.HitEntity, hitscan.Damage);
|
||||
if (modifiedDamage != null)
|
||||
_logs.Add(LogType.HitScanHit,
|
||||
$"{EntityManager.ToPrettyString(shooter):user} hit {EntityManager.ToPrettyString(result.HitEntity):target} using {EntityManager.ToPrettyString(hitscan.Owner):used} and dealt {dmg.Total:damage} damage");
|
||||
$"{EntityManager.ToPrettyString(shooter):user} hit {EntityManager.ToPrettyString(result.HitEntity):target} using {EntityManager.ToPrettyString(hitscan.Owner):used} and dealt {modifiedDamage.Total:damage} damage");
|
||||
|
||||
PlaySound(rayCastResults[0].HitEntity, modifiedDamage, hitscan.SoundHit, hitscan.ForceSound);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -251,4 +257,46 @@ public sealed partial class GunSystem
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Impact sounds
|
||||
|
||||
public void PlaySound(EntityUid otherEntity, DamageSpecifier? modifiedDamage, SoundSpecifier? weaponSound, bool forceWeaponSound)
|
||||
{
|
||||
// Like projectiles and melee,
|
||||
// 1. Entity specific sound
|
||||
// 2. Ammo's sound
|
||||
// 3. Nothing
|
||||
var playedSound = false;
|
||||
|
||||
if (!forceWeaponSound && modifiedDamage != null && modifiedDamage.Total > 0 && TryComp<RangedDamageSoundComponent>(otherEntity, out var rangedSound))
|
||||
{
|
||||
var type = MeleeWeaponSystem.GetHighestDamageSound(modifiedDamage, _protoManager);
|
||||
|
||||
if (type != null && rangedSound.SoundTypes?.TryGetValue(type, out var damageSoundType) == true)
|
||||
{
|
||||
SoundSystem.Play(
|
||||
Filter.Pvs(otherEntity, entityManager: EntityManager),
|
||||
damageSoundType!.GetSound(),
|
||||
otherEntity,
|
||||
AudioHelpers.WithVariation(DamagePitchVariation));
|
||||
|
||||
playedSound = true;
|
||||
}
|
||||
else if (type != null && rangedSound.SoundGroups?.TryGetValue(type, out var damageSoundGroup) == true)
|
||||
{
|
||||
SoundSystem.Play(
|
||||
Filter.Pvs(otherEntity, entityManager: EntityManager),
|
||||
damageSoundGroup!.GetSound(),
|
||||
otherEntity,
|
||||
AudioHelpers.WithVariation(DamagePitchVariation));
|
||||
|
||||
playedSound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!playedSound && weaponSound != null)
|
||||
SoundSystem.Play(Filter.Pvs(otherEntity, entityManager: EntityManager), weaponSound.GetSound(), otherEntity);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Hands.Components;
|
||||
using Content.Server.PowerCell;
|
||||
using Content.Server.Stunnable;
|
||||
using Content.Server.Weapon.Melee;
|
||||
using Content.Server.Weapon.Ranged.Ammunition.Components;
|
||||
using Content.Server.Weapon.Ranged.Barrels.Components;
|
||||
using Content.Shared.ActionBlocker;
|
||||
@@ -22,6 +23,7 @@ using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -30,6 +32,7 @@ namespace Content.Server.Weapon.Ranged;
|
||||
public sealed partial class GunSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
|
||||
[Dependency] private readonly AdminLogSystem _logs = default!;
|
||||
@@ -44,6 +47,8 @@ public sealed partial class GunSystem : EntitySystem
|
||||
[Dependency] private readonly StunSystem _stun = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
|
||||
public const float DamagePitchVariation = MeleeWeaponSystem.DamagePitchVariation;
|
||||
|
||||
/// <summary>
|
||||
/// How many sounds are allowed to be played on ejecting multiple casings.
|
||||
/// </summary>
|
||||
|
||||
30
Content.Server/Weapon/Ranged/RangedDamageSoundComponent.cs
Normal file
30
Content.Server/Weapon/Ranged/RangedDamageSoundComponent.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||
|
||||
namespace Content.Server.Weapon.Ranged;
|
||||
|
||||
/// <summary>
|
||||
/// Plays the specified sound upon receiving damage of that type.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed class RangedDamageSoundComponent : Component
|
||||
{
|
||||
// TODO: Limb damage changing sound type.
|
||||
|
||||
/// <summary>
|
||||
/// Specified sounds to apply when the entity takes damage with the specified group.
|
||||
/// Will fallback to defaults if none specified.
|
||||
/// </summary>
|
||||
[ViewVariables, DataField("soundGroups",
|
||||
customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageGroupPrototype>))]
|
||||
public Dictionary<string, SoundSpecifier>? SoundGroups;
|
||||
|
||||
/// <summary>
|
||||
/// Specified sounds to apply when the entity takes damage with the specified type.
|
||||
/// Will fallback to defaults if none specified.
|
||||
/// </summary>
|
||||
[ViewVariables, DataField("soundTypes",
|
||||
customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageTypePrototype>))]
|
||||
public Dictionary<string, SoundSpecifier>? SoundTypes;
|
||||
}
|
||||
Reference in New Issue
Block a user