More dynamic melee sounds (#8207)

This commit is contained in:
metalgearsloth
2022-05-17 13:49:07 +10:00
committed by GitHub
parent 825d7c4230
commit 8589f52bd5
23 changed files with 215 additions and 28 deletions

View File

@@ -10,8 +10,8 @@ using Content.Shared.Damage;
using Content.Shared.Sound;
using Content.Shared.Audio;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Hands;
using Content.Shared.Interaction;
using Content.Shared.Physics;
using Content.Shared.Weapons.Melee;
using Robust.Shared.Audio;
@@ -19,18 +19,22 @@ using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Server.Weapon.Melee
{
public sealed class MeleeWeaponSystem : EntitySystem
{
[Dependency] private IGameTiming _gameTiming = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private SolutionContainerSystem _solutionsSystem = default!;
[Dependency] private readonly SolutionContainerSystem _solutionsSystem = default!;
[Dependency] private readonly AdminLogSystem _logSystem = default!;
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
private const float DamagePitchVariation = 0.15f;
public override void Initialize()
{
base.Initialize();
@@ -73,7 +77,7 @@ namespace Content.Server.Weapon.Melee
if (curTime < comp.CooldownEnd || args.Target == null)
return;
var location = EntityManager.GetComponent<TransformComponent>(args.User).Coordinates;
var location = Transform(args.User).Coordinates;
var diff = args.ClickLocation.ToMapPos(EntityManager) - location.ToMapPos(EntityManager);
var angle = Angle.FromWorldVec(diff);
@@ -103,19 +107,12 @@ 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");
}
if (hitEvent.HitSoundOverride != null)
{
SoundSystem.Play(Filter.Pvs(owner), hitEvent.HitSoundOverride.GetSound(), target, AudioHelpers.WithVariation(0.25f));
}
else
{
SoundSystem.Play(Filter.Pvs(owner), comp.HitSound.GetSound(), target);
}
PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, comp.HitSound);
}
}
else
{
SoundSystem.Play(Filter.Pvs(owner), comp.MissSound.GetSound(), args.User);
SoundSystem.Play(Filter.Pvs(owner, entityManager: EntityManager), comp.MissSound.GetSound(), args.User);
return;
}
@@ -161,24 +158,20 @@ namespace Content.Server.Weapon.Melee
if (!hitEvent.Handled)
{
var modifiedDamage = DamageSpecifier.ApplyModifierSets(comp.Damage + hitEvent.BonusDamage, hitEvent.ModifiersList);
if (entities.Count != 0)
{
if (hitEvent.HitSoundOverride != null)
{
SoundSystem.Play(Filter.Pvs(owner), hitEvent.HitSoundOverride.GetSound(), Transform(entities.First()).Coordinates);
}
else
{
SoundSystem.Play(Filter.Pvs(owner), comp.HitSound.GetSound(), Transform(entities.First()).Coordinates);
}
var target = entities.First();
TryComp<MeleeWeaponComponent>(target, out var meleeWeapon);
PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, meleeWeapon?.HitSound);
}
else
{
SoundSystem.Play(Filter.Pvs(owner), comp.MissSound.GetSound(), Transform(args.User).Coordinates);
}
var modifiedDamage = DamageSpecifier.ApplyModifierSets(comp.Damage + hitEvent.BonusDamage, hitEvent.ModifiersList);
foreach (var entity in hitEntities)
{
RaiseLocalEvent(entity, new AttackedEvent(args.Used, args.User, args.ClickLocation));
@@ -203,6 +196,89 @@ namespace Content.Server.Weapon.Melee
RaiseLocalEvent(owner, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false);
}
private string? GetHighestDamageSound(DamageSpecifier modifiedDamage)
{
var groups = modifiedDamage.GetDamagePerGroup(_protoManager);
// Use group if it's exclusive, otherwise fall back to type.
if (groups.Count == 1)
{
return groups.Keys.First();
}
var highestDamage = FixedPoint2.Zero;
string? highestDamageType = null;
foreach (var (type, damage) in modifiedDamage.DamageDict)
{
if (damage <= highestDamage) continue;
highestDamageType = type;
}
return highestDamageType;
}
private void PlayHitSound(EntityUid target, string? type, SoundSpecifier? hitSoundOverride, SoundSpecifier? hitSound)
{
var playedSound = false;
// Play sound based off of highest damage type.
if (TryComp<MeleeSoundComponent>(target, out var damageSoundComp))
{
if (type == null && damageSoundComp.NoDamageSound != null)
{
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), damageSoundComp.NoDamageSound.GetSound(), target, AudioHelpers.WithVariation(DamagePitchVariation));
playedSound = true;
}
else if (type != null && damageSoundComp.SoundTypes?.TryGetValue(type, out var damageSoundType) == true)
{
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), damageSoundType!.GetSound(), target, AudioHelpers.WithVariation(DamagePitchVariation));
playedSound = true;
}
else if (type != null && damageSoundComp.SoundGroups?.TryGetValue(type, out var damageSoundGroup) == true)
{
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), damageSoundGroup!.GetSound(), target, AudioHelpers.WithVariation(DamagePitchVariation));
playedSound = true;
}
}
// Use weapon sounds if the thing being hit doesn't specify its own sounds.
if (!playedSound)
{
if (hitSoundOverride != null)
{
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), hitSoundOverride.GetSound(), target, AudioHelpers.WithVariation(DamagePitchVariation));
playedSound = true;
}
else if (hitSound != null)
{
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), hitSound.GetSound(), target);
playedSound = true;
}
}
// Fallback to generic sounds.
if (!playedSound)
{
switch (type)
{
// Unfortunately heat returns caustic group so can't just use the damagegroup in that instance.
case "Burn":
case "Heat":
case "Cold":
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), "/Audio/Items/welder.ogg", target);
break;
// No damage, fallback to tappies
case null:
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), "/Audio/Weapons/tap.ogg", target);
break;
case "Brute":
SoundSystem.Play(Filter.Pvs(target, entityManager: EntityManager), "/Audio/Weapons/smash.ogg", target);
break;
}
}
}
private HashSet<EntityUid> ArcRayCast(Vector2 position, Angle angle, float arcWidth, float range, MapId mapId, EntityUid ignore)
{
var widthRad = Angle.FromDegrees(arcWidth);