From 53e4097bbfc58ffd342d9a2edff3090129a61ced Mon Sep 17 00:00:00 2001 From: Sir Warock <67167466+SirWarock@users.noreply.github.com> Date: Sat, 3 Jan 2026 14:27:35 +0100 Subject: [PATCH] New Surgery UI (#5107) * One Commit ops * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Remove one Line * Readonly variable * Better Switch cases * Actually better this way --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .../Sheetlets/SurgeryTextureButtonSheetlet.cs | 43 +++++++ .../_Shitmed/Medical/Surgery/SurgeryBui.cs | 118 +++++++++++++++++- .../Medical/Surgery/SurgeryWindow.xaml | 95 +++++++++++--- .../Medical/Surgery/SurgeryWindow.xaml.cs | 20 ++- .../SurgeryUI/surgeryUIBackground.png | Bin 0 -> 382 bytes .../Interface/SurgeryUI/surgeryUICarp.png | Bin 0 -> 368 bytes .../Interface/SurgeryUI/surgeryUIHead.png | Bin 0 -> 170 bytes .../Interface/SurgeryUI/surgeryUILArm.png | Bin 0 -> 150 bytes .../Interface/SurgeryUI/surgeryUILFoot.png | Bin 0 -> 120 bytes .../Interface/SurgeryUI/surgeryUILHand.png | Bin 0 -> 128 bytes .../Interface/SurgeryUI/surgeryUILLeg.png | Bin 0 -> 129 bytes .../Interface/SurgeryUI/surgeryUIRArm.png | Bin 0 -> 142 bytes .../Interface/SurgeryUI/surgeryUIRFoot.png | Bin 0 -> 119 bytes .../Interface/SurgeryUI/surgeryUIRHand.png | Bin 0 -> 131 bytes .../Interface/SurgeryUI/surgeryUIRLeg.png | Bin 0 -> 132 bytes .../Interface/SurgeryUI/surgeryUITorso.png | Bin 0 -> 245 bytes 16 files changed, 249 insertions(+), 27 deletions(-) create mode 100644 Content.Client/_DV/Stylesheets/Sheetlets/SurgeryTextureButtonSheetlet.cs create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIBackground.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUICarp.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIHead.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILArm.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILFoot.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILHand.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILLeg.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRArm.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRFoot.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRHand.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRLeg.png create mode 100644 Resources/Textures/_Shitmed/Interface/SurgeryUI/surgeryUITorso.png diff --git a/Content.Client/_DV/Stylesheets/Sheetlets/SurgeryTextureButtonSheetlet.cs b/Content.Client/_DV/Stylesheets/Sheetlets/SurgeryTextureButtonSheetlet.cs new file mode 100644 index 0000000000..a3e51b78d5 --- /dev/null +++ b/Content.Client/_DV/Stylesheets/Sheetlets/SurgeryTextureButtonSheetlet.cs @@ -0,0 +1,43 @@ +using Content.Client.Stylesheets; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using static Content.Client.Stylesheets.StylesheetHelpers; + +namespace Content.Client._DV.Stylesheets.Sheetlets; + +[CommonSheetlet] +public sealed class SurgeryTextureButtonSheetlet : Sheetlet where T : PalettedStylesheet +{ + private readonly Color _dollColor = Color.FromHex("#639bff"); + public override StyleRule[] GetRules(T sheet, object config) + { + return + [ + E() + .Identifier("SurgeryTextureButton") + .PseudoHovered() + .Modulate(sheet.PositivePalette.HoveredElement), + E() + .Identifier("SurgeryTextureButton") + .PseudoPressed() + .Modulate(sheet.PositivePalette.PressedElement), + E() + .Identifier("SurgeryTextureButton") + .PseudoNormal() + .Modulate(_dollColor), + + E() + .Identifier("OpenIncision") + .PseudoHovered() + .Modulate(sheet.PositivePalette.HoveredElement), + E() + .Identifier("OpenIncision") + .PseudoPressed() + .Modulate(sheet.PositivePalette.PressedElement), + E() + .Identifier("OpenIncision") + .PseudoNormal() + .Modulate(sheet.HighlightPalette.HoveredElement), + ]; + } +} diff --git a/Content.Client/_Shitmed/Medical/Surgery/SurgeryBui.cs b/Content.Client/_Shitmed/Medical/Surgery/SurgeryBui.cs index 8767c8e241..935b726806 100644 --- a/Content.Client/_Shitmed/Medical/Surgery/SurgeryBui.cs +++ b/Content.Client/_Shitmed/Medical/Surgery/SurgeryBui.cs @@ -1,11 +1,14 @@ using Content.Client._Shitmed.Choice.UI; using Content.Client.Administration.UI.CustomControls; using Content.Shared._Shitmed.Medical.Surgery; +using Content.Shared._Shitmed.Medical.Surgery.Steps.Parts; // DeltaV - New UI using Content.Shared.Body.Components; using Content.Shared.Body.Part; +using Content.Shared.Humanoid; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Player; +using Robust.Client.UserInterface.Controls; // DeltaV - New UI using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -24,6 +27,7 @@ public sealed class SurgeryBui : BoundUserInterface private bool _isBody; private (EntityUid Ent, EntProtoId Proto)? _surgery; private readonly List _previousSurgeries = new(); + private (EntityUid Ent, TextureButton)? _previousPart; // DeltaV - New UI public SurgeryBui(EntityUid owner, Enum uiKey) : base(owner, uiKey) => _system = _entities.System(); protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -64,6 +68,7 @@ public sealed class SurgeryBui : BoundUserInterface _isBody = false; _surgery = null; _previousSurgeries.Clear(); + DeactivateOtherParts(); // DeltaV - New UI View(ViewType.Parts); }; @@ -138,16 +143,37 @@ public sealed class SurgeryBui : BoundUserInterface return GetScore(a.PartType) - GetScore(b.PartType); }); - foreach (var (netEntity, entity, partName, _) in options) + // DeltaV Start - New UI + foreach (var textureButton in _window.Buttons) + { + textureButton.Visible = false; + textureButton.StyleIdentifier = "SurgeryTextureButton"; + } + // DeltaV End - New UI + + foreach (var (netEntity, entity, partName, bodyPartType) in options) // DeltaV - New UI { //var netPart = _entities.GetNetEntity(part.Owner); var surgeries = state.Choices[netEntity]; - var partButton = new ChoiceControl(); - partButton.Set(partName, null); - partButton.Button.OnPressed += _ => OnPartPressed(netEntity, surgeries); + // Delta Start - New UI + var button = GetBodyPartTextureButton(entity, bodyPartType); + if (button != null) + { + button.Visible = true; + button.OnPressed += _ => OnPartPressed(netEntity, surgeries); + if (_entities.HasComponent(entity)) + button.StyleIdentifier = "OpenIncision"; + } + else + { + var partButton = new ChoiceControl(); - _window.Parts.AddChild(partButton); + partButton.Set(partName, null); + partButton.Button.OnPressed += _ => OnPartPressed(netEntity, surgeries); + _window.Parts.AddChild(partButton); + } + // Delta End - New UI foreach (var surgeryId in surgeries) { @@ -227,7 +253,35 @@ public sealed class SurgeryBui : BoundUserInterface _part = _entities.GetEntity(netPart); _isBody = _entities.HasComponent(_part); - var body = _entities.GetComponent(_part.Value).Body!.Value; // DeltaV + // DeltaV Start - New UI + var bodyPart = _entities.GetComponent(_part.Value); + var body = bodyPart.Body!.Value; + + if (_previousPart != null) + { + (var previousEnt, var previousButton) = _previousPart.Value; + if (!_entities.HasComponent(previousEnt)) + previousButton.StyleIdentifier = "SurgeryTextureButton"; + } + + var button = GetBodyPartTextureButton(_part.Value, bodyPart.PartType); + if (button != null && button.Pressed) + { + _previousPart = (_part.Value, button); + DeactivateOtherParts(button); + } + else if (button != null && !button.Pressed) + { + _part = null; + _isBody = false; + _surgery = null; + _previousSurgeries.Clear(); + View(ViewType.Parts); + + return; + } + // DeltaV End - New UI + _window.Surgeries.RemoveAllChildren(); var surgeries = new List<(Entity Ent, EntProtoId Id, string Name)>(); @@ -277,6 +331,58 @@ public sealed class SurgeryBui : BoundUserInterface View(ViewType.Surgeries); } + // DeltaV Start - New UI + private TextureButton? GetBodyPartTextureButton(EntityUid entity, BodyPartType? partType) + { + if (_window == null + || !_entities.TryGetComponent(entity, out BodyPartComponent? bodyPart)) + return null; + + var isLeftPart = bodyPart.Symmetry.HasFlag(BodyPartSymmetry.Left); + + switch (partType) + { + case BodyPartType.Torso: + var isHumanoid = _entities.HasComponent(bodyPart.Body); + return isHumanoid ? _window.ChestButton : _window.CarpButton; + case BodyPartType.Head: + return _window.HeadButton; + case BodyPartType.Arm: + return isLeftPart ? _window.LArmButton : _window.RArmButton; + case BodyPartType.Hand: + return isLeftPart ? _window.LHandButton : _window.RHandButton; + case BodyPartType.Leg: + return isLeftPart ? _window.LLegButton : _window.RLegButton; + case BodyPartType.Foot: + return isLeftPart ? _window.LFootButton : _window.RFootButton; + case BodyPartType.Tail: + case BodyPartType.Other: + case null: + return null; + default: + throw new ArgumentOutOfRangeException(nameof(partType), partType, null); + } + } + + /// + /// Deactivates all other buttons that are currently active. + /// + /// The button that should be the only active button. + private void DeactivateOtherParts(TextureButton? activatedButton = null) + { + if (_window == null) + return; + + foreach (var button in _window.Buttons) + { + if (activatedButton == button) + continue; + + button.Pressed = false; + } + } + // DeltaV End - New UI + private void RefreshUI() { if (_window == null diff --git a/Content.Client/_Shitmed/Medical/Surgery/SurgeryWindow.xaml b/Content.Client/_Shitmed/Medical/Surgery/SurgeryWindow.xaml index 433e927a25..33424a449d 100644 --- a/Content.Client/_Shitmed/Medical/Surgery/SurgeryWindow.xaml +++ b/Content.Client/_Shitmed/Medical/Surgery/SurgeryWindow.xaml @@ -1,23 +1,80 @@ - - - -