HealingSystem: check blood restoration, staunching (#33526)

* HealingSystem: check blood restoration, staunching

* Milon's suggestions

* beck-thompson's requests

(cherry picked from commit 5092681729cadd56c6194ab42c1f7c3e96e96e6e)
This commit is contained in:
Whatstone
2025-02-05 06:23:30 +03:00
committed by Spatison
parent 9a905abaed
commit 6ed071f0e8

View File

@@ -4,8 +4,10 @@ using Content.Server.Body.Systems;
using Content.Server.Medical.Components;
using Content.Server.Popups;
using Content.Server.Stack;
using Content.Shared._Shitmed.Targeting;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Audio;
using Content.Shared.Body.Systems;
using Content.Shared.Damage;
using Content.Shared.Database;
using Content.Shared.DoAfter;
@@ -22,10 +24,6 @@ using Content.Shared.Stacks;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Random;
// Shitmed Change
using Content.Shared.Body.Systems;
using Content.Shared._Shitmed.Targeting;
namespace Content.Server.Medical;
public sealed class HealingSystem : EntitySystem
@@ -33,7 +31,6 @@ 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 SharedTargetingSystem _targetingSystem = default!; // Shitmed Change
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly IRobustRandom _random = default!;
@@ -42,6 +39,7 @@ public sealed class HealingSystem : EntitySystem
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly SharedTargetingSystem _targetingSystem = default!; // Shitmed Change
[Dependency] private readonly SharedBodySystem _bodySystem = default!; // Shitmed Change
public override void Initialize()
@@ -123,16 +121,16 @@ public sealed class HealingSystem : EntitySystem
_audio.PlayPvs(healing.HealingEndSound, entity.Owner, AudioHelpers.WithVariation(0.125f, _random).WithVolume(-5f));
// Logic to determine whether or not to repeat the healing action
args.Repeat = HasDamage(entity.Comp, healing) && !dontRepeat || IsPartDamaged(args.User, entity); // Shitmed Change
// Logic to determine the whether or not to repeat the healing action
args.Repeat = HasDamage(entity, healing) && !dontRepeat || IsPartDamaged(args.User, entity); // Shitmed Change
if (!args.Repeat && !dontRepeat)
_popupSystem.PopupEntity(Loc.GetString("medical-item-finished-using", ("item", args.Used)), entity.Owner, args.User);
args.Handled = true;
}
private bool HasDamage(DamageableComponent component, HealingComponent healing)
private bool HasDamage(Entity<DamageableComponent> ent, HealingComponent healing)
{
var damageableDict = component.Damage.DamageDict;
var damageableDict = ent.Comp.Damage.DamageDict;
var healingDict = healing.Damage.DamageDict;
foreach (var type in healingDict)
{
@@ -142,6 +140,23 @@ public sealed class HealingSystem : EntitySystem
}
}
if (TryComp<BloodstreamComponent>(ent, out var bloodstream))
{
// Is ent missing blood that we can restore?
if (healing.ModifyBloodLevel > 0
&& _solutionContainerSystem.ResolveSolution(ent.Owner, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution)
&& bloodSolution.Volume < bloodSolution.MaxVolume)
{
return true;
}
// Is ent bleeding and can we stop it?
if (healing.BloodlossModifier < 0 && bloodstream.BleedAmount > 0)
{
return true;
}
}
return false;
}
@@ -198,15 +213,7 @@ public sealed class HealingSystem : EntitySystem
if (TryComp<StackComponent>(uid, out var stack) && stack.Count < 1)
return false;
var anythingToDo =
HasDamage(targetDamage, component) ||
IsPartDamaged(user, target) || // Shitmed Change
component.ModifyBloodLevel > 0 // Special case if healing item can restore lost blood...
&& TryComp<BloodstreamComponent>(target, out var bloodstream)
&& _solutionContainerSystem.ResolveSolution(target, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution)
&& bloodSolution.Volume < bloodSolution.MaxVolume; // ...and there is lost blood to restore.
if (!anythingToDo)
if (!(HasDamage((target, targetDamage), component) || IsPartDamaged(user, target))) // Shitmed Change
{
_popupSystem.PopupEntity(Loc.GetString("medical-item-cant-use", ("item", uid)), uid, user);
return false;
@@ -230,11 +237,10 @@ public sealed class HealingSystem : EntitySystem
var doAfterEventArgs =
new DoAfterArgs(EntityManager, user, delay, new HealingDoAfterEvent(), target, target: target, used: uid)
{
//Raise the event on the target if it's not self, otherwise raise it on self.
BreakOnMove = true,
// Didn't break on damage as they may be trying to prevent it and
// not being able to heal your own ticking damage would be frustrating.
NeedHand = true,
BreakOnMove = true,
BreakOnWeightlessMove = false,
};