diff --git a/Content.Client/Backmen/Targeting/TargetingSystem.cs b/Content.Client/Backmen/Targeting/TargetingSystem.cs index a3387022163..d5aa8b993cb 100644 --- a/Content.Client/Backmen/Targeting/TargetingSystem.cs +++ b/Content.Client/Backmen/Targeting/TargetingSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Backmen.Targeting; using Content.Shared.Input; using Content.Shared.Targeting; using Content.Shared.Targeting.Events; @@ -5,7 +6,7 @@ using Robust.Shared.Input.Binding; using Robust.Shared.Player; -namespace Content.Client.Targeting; +namespace Content.Client.Backmen.Targeting; public sealed class TargetingSystem : SharedTargetingSystem { [Dependency] private readonly IPlayerManager _playerManager = default!; @@ -91,4 +92,4 @@ private void HandleTargetChange(ICommonSession? session, TargetBodyPart target) TargetChange?.Invoke(target); } -} \ No newline at end of file +} diff --git a/Content.Client/Backmen/UserInterface/Systems/PartStatus/PartStatusUIController.cs b/Content.Client/Backmen/UserInterface/Systems/PartStatus/PartStatusUIController.cs index 3bd31f733bf..26b22b22a2d 100644 --- a/Content.Client/Backmen/UserInterface/Systems/PartStatus/PartStatusUIController.cs +++ b/Content.Client/Backmen/UserInterface/Systems/PartStatus/PartStatusUIController.cs @@ -1,7 +1,7 @@ using Content.Client.Backmen.UserInterface.Systems.PartStatus.Widgets; using Content.Client.Gameplay; using Content.Shared.Targeting; -using Content.Client.Targeting; +using Content.Client.Backmen.Targeting; using Robust.Client.GameObjects; using Robust.Client.UserInterface.Controllers; using Robust.Shared.Utility; diff --git a/Content.Client/Backmen/UserInterface/Systems/Targeting/TargetingUIController.cs b/Content.Client/Backmen/UserInterface/Systems/Targeting/TargetingUIController.cs index b5bb8f80db1..4967533d304 100644 --- a/Content.Client/Backmen/UserInterface/Systems/Targeting/TargetingUIController.cs +++ b/Content.Client/Backmen/UserInterface/Systems/Targeting/TargetingUIController.cs @@ -1,7 +1,7 @@ using Content.Client.Backmen.UserInterface.Systems.Targeting.Widgets; using Content.Client.Gameplay; using Content.Shared.Targeting; -using Content.Client.Targeting; +using Content.Client.Backmen.Targeting; using Content.Shared.Targeting.Events; using Robust.Client.UserInterface.Controllers; using Robust.Client.Player; diff --git a/Content.Server/Backmen/Targeting/TargetingSystem.cs b/Content.Server/Backmen/Targeting/TargetingSystem.cs index e2704b40a46..0da4884b03c 100644 --- a/Content.Server/Backmen/Targeting/TargetingSystem.cs +++ b/Content.Server/Backmen/Targeting/TargetingSystem.cs @@ -1,14 +1,12 @@ +using Content.Shared.Backmen.Targeting; using Content.Shared.Body.Systems; using Content.Shared.Mobs; using Content.Shared.Targeting; using Content.Shared.Targeting.Events; -using Robust.Server.Audio; -using Robust.Shared.Audio; -namespace Content.Server.Targeting; +namespace Content.Server.Backmen.Targeting; public sealed class TargetingSystem : SharedTargetingSystem { - [Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly SharedBodySystem _bodySystem = default!; public override void Initialize() @@ -54,4 +52,4 @@ private void OnMobStateChange(EntityUid uid, TargetingComponent component, MobSt RaiseNetworkEvent(new TargetIntegrityChangeEvent(GetNetEntity(uid)), uid); } } -} \ No newline at end of file +} diff --git a/Content.Server/Medical/HealingSystem.cs b/Content.Server/Medical/HealingSystem.cs index a1e26771c56..e135d3e0f25 100644 --- a/Content.Server/Medical/HealingSystem.cs +++ b/Content.Server/Medical/HealingSystem.cs @@ -91,25 +91,6 @@ entity.Comp.DamageContainerID is not null && if (healed == null && healing.BloodlossModifier != 0) return; - /* This is rather shitcodey. Problem is that right now damage is coupled to integrity. - If the body is fully healed, all of the checks on TryChangeDamage stop us from actually healing. - So in this case we add a special check to heal anyway if TryChangeDamage returns null. - */ - if (healed != null && healed.GetTotal() == 0) - { - if (TryComp(args.User, out var user) - && TryComp(args.Target, out var target) - && healing.Damage.GetTotal() < 0) - { - // If they are valid, we check for body part presence, - // and integrity, then apply a direct integrity change. - var (type, symmetry) = _bodySystem.ConvertTargetBodyPart(user.Target); - if (_bodySystem.GetBodyChildrenOfType(args.Target.Value, type, symmetry: symmetry).FirstOrDefault() is { } bodyPart - && bodyPart.Component.Integrity < BodyPartComponent.MaxIntegrity) - _bodySystem.TryChangeIntegrity(bodyPart, healing.Damage.GetTotal().Float(), false, target.Target, out var _); - } - } - var total = healed?.GetTotal() ?? FixedPoint2.Zero; // Re-verify that we can heal the damage. @@ -126,6 +107,24 @@ entity.Comp.DamageContainerID is not null && QueueDel(args.Used.Value); } + // start-backmen: surgery + // This is still pretty shitcodey, but a lot better than previous iteration. + // We are just trying to heal the most damaged body part. + if (healed != null && healed.GetTotal() == 0) + { + var parts = _bodySystem.GetBodyChildren(args.Target).ToList(); + // Get the severest body part, selected by taking the one with lowest Integrity. + var severestPart = parts.MinBy(x => x.Component.Integrity); + // Convert this thing into a target + var targetBodyPart = _bodySystem.GetTargetBodyPart(severestPart); + + if (targetBodyPart != null) + { + _bodySystem.TryChangeIntegrity(severestPart, healing.Damage.GetTotal().Float(), false, targetBodyPart.Value, out _); + } + } + // end-backmen: surgery + if (entity.Owner != args.User) { _adminLogger.Add(LogType.Healed, diff --git a/Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs b/Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs index ada167aa4e3..9a5c37466d8 100644 --- a/Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs +++ b/Content.Shared/Backmen/Surgery/Body/SharedBodySystem.Integrity.cs @@ -157,7 +157,7 @@ public void TryChangeIntegrity(Entity partEnt, RaiseLocalEvent(partEnt, ref ev); } - if (partEnt.Comp.Integrity != originalIntegrity + if (Math.Abs(partEnt.Comp.Integrity - originalIntegrity) > 0.01 && _queryTargeting.TryComp(partEnt.Comp.Body, out var targeting) && HasComp(partEnt.Comp.Body)) { diff --git a/Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs b/Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs index 9d79622da6f..b0d7356ad77 100644 --- a/Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs +++ b/Content.Shared/Backmen/Targeting/SharedTargetingSystem.cs @@ -1,10 +1,3 @@ -namespace Content.Shared.Targeting; -public abstract class SharedTargetingSystem : EntitySystem -{ - public override void Initialize() - { - base.Initialize(); - } +namespace Content.Shared.Backmen.Targeting; - -} \ No newline at end of file +public abstract class SharedTargetingSystem : EntitySystem; diff --git a/Content.Shared/Body/Part/BodyPartComponent.cs b/Content.Shared/Body/Part/BodyPartComponent.cs index 23ad3c8b6b0..7e2168c899c 100644 --- a/Content.Shared/Body/Part/BodyPartComponent.cs +++ b/Content.Shared/Body/Part/BodyPartComponent.cs @@ -2,6 +2,7 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.Body.Components; using Content.Shared.Body.Systems; +using Content.Shared.FixedPoint; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Serialization; @@ -36,6 +37,13 @@ public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent [DataField("vital"), AutoNetworkedField] public bool IsVital; + /// + /// Amount of damage to deal when the part gets removed. + /// Only works if IsVital is true. + /// + [DataField, AutoNetworkedField] + public FixedPoint2 VitalDamage = MaxIntegrity; + [DataField, AutoNetworkedField] public BodyPartSymmetry Symmetry = BodyPartSymmetry.None; diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs index e0e9d4c2009..5628f6bd63d 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs @@ -275,8 +275,8 @@ private void PartRemoveDamage(Entity bodyEnt, Entity("Bloodloss"), 300); - Damageable.TryChangeDamage(bodyEnt, damage); + var damage = new DamageSpecifier(Prototypes.Index("Bloodloss"), partEnt.Comp.VitalDamage); + Damageable.TryChangeDamage(bodyEnt, damage, partMultiplier: 0f); } } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/furniture/tables/operating_table.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/furniture/tables/operating_table.ftl index bc4fad5d91c..c6b9ca05fd1 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/furniture/tables/operating_table.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/furniture/tables/operating_table.ftl @@ -1,2 +1,2 @@ ent-OperatingTable = операционный стол - .desc = Специальный медицинский стол для проведения операций. Впрочем, сейчас это просто бесполезный реквизит. + .desc = Специальный медицинский стол для проведения операций. Смотря на него у вас неожиданно возникает ощущение быстрого течения времени...