diff --git a/Content.Server/Medical/HealingSystem.cs b/Content.Server/Medical/HealingSystem.cs index d3664d4ad9..46b39a460e 100644 --- a/Content.Server/Medical/HealingSystem.cs +++ b/Content.Server/Medical/HealingSystem.cs @@ -10,18 +10,20 @@ using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; +using Content.Shared.MobState.Components; using Content.Shared.Stacks; -using Robust.Shared.Audio; -using Robust.Shared.Player; +using Robust.Shared.Random; namespace Content.Server.Medical; public sealed class HealingSystem : EntitySystem { + [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; [Dependency] private readonly DoAfterSystem _doAfter = default!; + [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly StackSystem _stacks = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!; @@ -40,10 +42,12 @@ public sealed class HealingSystem : EntitySystem if (_mobStateSystem.IsDead(uid)) return; - if (TryComp(args.Component.Owner, out var stack) && stack.Count < 1) return; + if (TryComp(args.Component.Owner, out var stack) && stack.Count < 1) + return; if (component.DamageContainerID is not null && - !component.DamageContainerID.Equals(component.DamageContainerID)) return; + !component.DamageContainerID.Equals(component.DamageContainerID)) + return; if (args.Component.BloodlossModifier != 0) { @@ -66,7 +70,8 @@ public sealed class HealingSystem : EntitySystem if (args.Component.HealingEndSound != null) { - SoundSystem.Play(args.Component.HealingEndSound.GetSound(), Filter.Pvs(uid, entityManager:EntityManager), uid, AudioHelpers.WithVariation(0.125f).WithVolume(-5f)); + _audio.PlayPvs(args.Component.HealingEndSound, uid, + AudioHelpers.WithVariation(0.125f, _random).WithVolume(-5f)); } } @@ -77,7 +82,8 @@ public sealed class HealingSystem : EntitySystem private void OnHealingUse(EntityUid uid, HealingComponent component, UseInHandEvent args) { - if (args.Handled) return; + if (args.Handled) + return; if (TryHeal(uid, args.User, args.User, component)) args.Handled = true; @@ -85,7 +91,8 @@ public sealed class HealingSystem : EntitySystem private void OnHealingAfterInteract(EntityUid uid, HealingComponent component, AfterInteractEvent args) { - if (args.Handled || !args.CanReach || args.Target == null) return; + if (args.Handled || !args.CanReach || args.Target == null) + return; if (TryHeal(uid, args.User, args.Target.Value, component)) args.Handled = true; @@ -123,13 +130,13 @@ public sealed class HealingSystem : EntitySystem if (component.HealingBeginSound != null) { - SoundSystem.Play(component.HealingBeginSound.GetSound(), Filter.Pvs(uid, entityManager:EntityManager), uid, AudioHelpers.WithVariation(0.125f).WithVolume(-5f)); + _audio.PlayPvs(component.HealingBeginSound, uid, + AudioHelpers.WithVariation(0.125f, _random).WithVolume(-5f)); } - var delay = component.Delay; - - if (user == target) - delay *= component.SelfHealPenaltyMultiplier; + var delay = user != target + ? component.Delay + : component.Delay * GetScaledHealingPenalty(user, component); _doAfter.DoAfter(new DoAfterEventArgs(user, delay, component.CancelToken.Token, target) { @@ -159,6 +166,25 @@ public sealed class HealingSystem : EntitySystem return true; } + /// + /// Scales the self-heal penalty based on the amount of damage taken + /// + /// + /// + /// + public float GetScaledHealingPenalty(EntityUid uid, HealingComponent component) + { + var output = component.Delay; + if (!TryComp(uid, out var mobState) || !TryComp(uid, out var damageable)) + return output; + + _mobStateSystem.TryGetEarliestCriticalState(mobState, 0, out var _, out var amount); + var percentDamage = (float) (damageable.TotalDamage / amount); + //basically make it scale from 1 to the multiplier. + var modifier = percentDamage * (component.SelfHealPenaltyMultiplier - 1) + 1; + return Math.Max(modifier, 1); + } + private sealed class HealingCompleteEvent : EntityEventArgs { public EntityUid User;