[Add] Repeatable healing items (#15613)

* repeatable healing items

* comments and break

* simplified and improved

* added messages

* improved messages

* stops when bleeding stops and won't give popup when clicking on an unhealable object

* should actually stop when bleeding stops now

* rerun tests please github

* changes made

* rerun tests please github

* remove braces

* fix
This commit is contained in:
OctoRocket
2023-04-23 23:34:18 -05:00
committed by GitHub
parent b9b5370e4e
commit 705d7ccf54
2 changed files with 50 additions and 4 deletions

View File

@@ -1,4 +1,5 @@
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Body.Components;
using Content.Server.Body.Systems; using Content.Server.Body.Systems;
using Content.Server.Medical.Components; using Content.Server.Medical.Components;
using Content.Server.Stack; using Content.Server.Stack;
@@ -14,6 +15,7 @@ using Content.Shared.Mobs;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Stacks; using Content.Shared.Stacks;
using Content.Server.Popups;
using Robust.Shared.Random; using Robust.Shared.Random;
namespace Content.Server.Medical; namespace Content.Server.Medical;
@@ -30,6 +32,7 @@ public sealed class HealingSystem : EntitySystem
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!; [Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -41,6 +44,8 @@ public sealed class HealingSystem : EntitySystem
private void OnDoAfter(EntityUid uid, DamageableComponent component, HealingDoAfterEvent args) private void OnDoAfter(EntityUid uid, DamageableComponent component, HealingDoAfterEvent args)
{ {
var dontRepeat = false;
if (!TryComp(args.Used, out HealingComponent? healing)) if (!TryComp(args.Used, out HealingComponent? healing))
return; return;
@@ -52,7 +57,17 @@ public sealed class HealingSystem : EntitySystem
// Heal some bloodloss damage. // Heal some bloodloss damage.
if (healing.BloodlossModifier != 0) if (healing.BloodlossModifier != 0)
{
if (!TryComp<BloodstreamComponent>(uid, out var bloodstream))
return;
var isBleeding = bloodstream.BleedAmount > 0;
_bloodstreamSystem.TryModifyBleedAmount(uid, healing.BloodlossModifier); _bloodstreamSystem.TryModifyBleedAmount(uid, healing.BloodlossModifier);
if (isBleeding != bloodstream.BleedAmount > 0)
{
dontRepeat = true;
_popupSystem.PopupEntity(Loc.GetString("medical-item-stop-bleeding"), uid);
}
}
// Restores missing blood // Restores missing blood
if (healing.ModifyBloodLevel != 0) if (healing.ModifyBloodLevel != 0)
@@ -65,21 +80,44 @@ public sealed class HealingSystem : EntitySystem
var total = healed?.Total ?? FixedPoint2.Zero; var total = healed?.Total ?? FixedPoint2.Zero;
// Reverify that we can heal the damage. // Re-verify that we can heal the damage.
_stacks.Use(args.Used.Value, 1); _stacks.Use(args.Used.Value, 1);
if (uid != args.User) if (uid != args.User)
{
_adminLogger.Add(LogType.Healed, _adminLogger.Add(LogType.Healed,
$"{EntityManager.ToPrettyString(args.User):user} healed {EntityManager.ToPrettyString(uid):target} for {total:damage} damage"); $"{EntityManager.ToPrettyString(args.User):user} healed {EntityManager.ToPrettyString(uid):target} for {total:damage} damage");
}
else else
{
_adminLogger.Add(LogType.Healed, _adminLogger.Add(LogType.Healed,
$"{EntityManager.ToPrettyString(args.User):user} healed themselves for {total:damage} damage"); $"{EntityManager.ToPrettyString(args.User):user} healed themselves for {total:damage} damage");
}
_audio.PlayPvs(healing.HealingEndSound, uid, AudioHelpers.WithVariation(0.125f, _random).WithVolume(-5f)); _audio.PlayPvs(healing.HealingEndSound, uid, AudioHelpers.WithVariation(0.125f, _random).WithVolume(-5f));
// Logic to determine the whether or not to repeat the healing action
args.Repeat = (HasDamage(component, healing) && !dontRepeat);
if (!args.Repeat && !dontRepeat)
_popupSystem.PopupEntity(Loc.GetString("medical-item-finished-using", ("item", args.Used)), uid);
args.Handled = true; args.Handled = true;
} }
private bool HasDamage(DamageableComponent component, HealingComponent healing)
{
var damageableDict = component.Damage.DamageDict;
var healingDict = healing.Damage.DamageDict;
foreach (var type in healingDict)
{
if (damageableDict[type.Key].Value > 0)
{
return true;
}
}
return false;
}
private void OnHealingUse(EntityUid uid, HealingComponent component, UseInHandEvent args) private void OnHealingUse(EntityUid uid, HealingComponent component, UseInHandEvent args)
{ {
if (args.Handled) if (args.Handled)
@@ -103,9 +141,6 @@ public sealed class HealingSystem : EntitySystem
if (_mobStateSystem.IsDead(target) || !TryComp<DamageableComponent>(target, out var targetDamage)) if (_mobStateSystem.IsDead(target) || !TryComp<DamageableComponent>(target, out var targetDamage))
return false; return false;
if (targetDamage.TotalDamage == 0)
return false;
if (component.DamageContainerID is not null && if (component.DamageContainerID is not null &&
!component.DamageContainerID.Equals(targetDamage.DamageContainerID)) !component.DamageContainerID.Equals(targetDamage.DamageContainerID))
return false; return false;
@@ -116,9 +151,17 @@ public sealed class HealingSystem : EntitySystem
if (!TryComp<StackComponent>(uid, out var stack) || stack.Count < 1) if (!TryComp<StackComponent>(uid, out var stack) || stack.Count < 1)
return false; return false;
if (!HasDamage(targetDamage, component))
{
_popupSystem.PopupEntity(Loc.GetString("medical-item-cant-use", ("item", uid)), uid);
return false;
}
if (component.HealingBeginSound != null) if (component.HealingBeginSound != null)
{
_audio.PlayPvs(component.HealingBeginSound, uid, _audio.PlayPvs(component.HealingBeginSound, uid,
AudioHelpers.WithVariation(0.125f, _random).WithVolume(-5f)); AudioHelpers.WithVariation(0.125f, _random).WithVolume(-5f));
}
var isNotSelf = user != target; var isNotSelf = user != target;

View File

@@ -0,0 +1,3 @@
medical-item-finished-using = You have finished healing with the {$item}
medical-item-cant-use = There is no damage you can heal with the {$item}
medical-item-stop-bleeding = They have stopped bleeding