[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:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user