From a39fa80d581019671745f97145cb931a2b16218a Mon Sep 17 00:00:00 2001 From: chromiumboy <50505512+chromiumboy@users.noreply.github.com> Date: Thu, 17 Aug 2023 12:22:01 -0500 Subject: [PATCH 01/21] Add lathe material ejection (#19218) This completes PilgrimViis' (now closed) PR 16398. It addresses issue 10896, by allowing materials to be ejected from most lathes (except the ore processor and sheet-meister 2000) * - Refinements to the material ejection UI - Made the lathe UI default to a slightly larger size - Fixed an offset issue with the label of the item currently being printed in the build queue UI * Allow the materiel reclamation UI to pop if there is material left in the lathe, but not enough to print any sheets --------- Co-authored-by: Kevin Zheng --- .../Lathe/UI/LatheBoundUserInterface.cs | 21 ++++++ .../Lathe/UI/LatheMaterialEjector.xaml | 21 ++++++ .../Lathe/UI/LatheMaterialEjector.xaml.cs | 64 ++++++++++++++++ .../Lathe/UI/LatheMaterialsEjectionMenu.xaml | 16 ++++ .../UI/LatheMaterialsEjectionMenu.xaml.cs | 74 +++++++++++++++++++ Content.Client/Lathe/UI/LatheMenu.xaml | 11 ++- Content.Client/Lathe/UI/LatheMenu.xaml.cs | 23 +++++- Content.Client/Lathe/UI/LatheQueueMenu.xaml | 7 +- Content.Server/Lathe/LatheSystem.cs | 32 ++++++++ Content.Shared/Lathe/LatheComponent.cs | 6 ++ .../Lathe/LatheEjectMaterialMessage.cs | 16 ++++ .../Locale/en-US/lathe/ui/lathe-menu.ftl | 5 +- .../Entities/Structures/Machines/lathe.yml | 2 + 13 files changed, 288 insertions(+), 10 deletions(-) create mode 100644 Content.Client/Lathe/UI/LatheMaterialEjector.xaml create mode 100644 Content.Client/Lathe/UI/LatheMaterialEjector.xaml.cs create mode 100644 Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml create mode 100644 Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml.cs create mode 100644 Content.Shared/Lathe/LatheEjectMaterialMessage.cs diff --git a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs index 35094cecabe12b..ab44d0f5a2f2f7 100644 --- a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs +++ b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs @@ -14,6 +14,9 @@ public sealed class LatheBoundUserInterface : BoundUserInterface [ViewVariables] private LatheQueueMenu? _queueMenu; + [ViewVariables] + private LatheMaterialsEjectionMenu? _materialsEjectionMenu; + public LatheBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -24,6 +27,7 @@ protected override void Open() _menu = new LatheMenu(this); _queueMenu = new LatheQueueMenu(); + _materialsEjectionMenu = new LatheMaterialsEjectionMenu(); _menu.OnClose += Close; @@ -34,15 +38,30 @@ protected override void Open() else _queueMenu.OpenCenteredLeft(); }; + + _menu.OnMaterialsEjectionButtonPressed += _ => + { + if (_materialsEjectionMenu.IsOpen) + _materialsEjectionMenu.Close(); + else + _materialsEjectionMenu.OpenCenteredRight(); + }; + _menu.OnServerListButtonPressed += _ => { SendMessage(new ConsoleServerSelectionMessage()); }; + _menu.RecipeQueueAction += (recipe, amount) => { SendMessage(new LatheQueueRecipeMessage(recipe, amount)); }; + _materialsEjectionMenu.OnEjectPressed += (material, sheetsToExtract) => + { + SendMessage(new LatheEjectMaterialMessage(material, sheetsToExtract)); + }; + _menu.OpenCentered(); } @@ -59,6 +78,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _menu?.PopulateMaterials(Owner); _queueMenu?.PopulateList(msg.Queue); _queueMenu?.SetInfo(msg.CurrentlyProducing); + _materialsEjectionMenu?.PopulateMaterials(Owner); break; } } @@ -70,6 +90,7 @@ protected override void Dispose(bool disposing) return; _menu?.Dispose(); _queueMenu?.Dispose(); + _materialsEjectionMenu?.Dispose(); } } } diff --git a/Content.Client/Lathe/UI/LatheMaterialEjector.xaml b/Content.Client/Lathe/UI/LatheMaterialEjector.xaml new file mode 100644 index 00000000000000..713b49aa5c836b --- /dev/null +++ b/Content.Client/Lathe/UI/LatheMaterialEjector.xaml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/Content.Client/Lathe/UI/LatheMaterialEjector.xaml.cs b/Content.Client/Lathe/UI/LatheMaterialEjector.xaml.cs new file mode 100644 index 00000000000000..090a189c71c355 --- /dev/null +++ b/Content.Client/Lathe/UI/LatheMaterialEjector.xaml.cs @@ -0,0 +1,64 @@ +using Content.Shared.Materials; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Prototypes; + +namespace Content.Client.Lathe.UI; + +/// +/// This widget is one row in the lathe eject menu. +/// + +[GenerateTypedNameReferences] +public sealed partial class LatheMaterialEjector : PanelContainer +{ + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + public string Material; + public Action? OnEjectPressed; + public int VolumePerSheet; + + public LatheMaterialEjector(string material, Action? onEjectPressed, int volumePerSheet, int maxEjectableSheets) + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + Material = material; + OnEjectPressed = onEjectPressed; + VolumePerSheet = volumePerSheet; + + PopulateButtons(maxEjectableSheets); + } + + public void PopulateButtons(int maxEjectableSheets) + { + int[] sheetsToEjectArray = { 1, 5, 10, 30 }; + + foreach (int sheetsToEject in sheetsToEjectArray) + { + var button = new Button() + { + Name = $"{sheetsToEject}", + Access = AccessLevel.Public, + Text = Loc.GetString($"{sheetsToEject}"), + MinWidth = 45, + }; + + button.OnPressed += (_) => + { + OnEjectPressed?.Invoke(Material, sheetsToEject); + }; + + button.Disabled = maxEjectableSheets < sheetsToEject; + + if (_prototypeManager.TryIndex(Material, out var proto)) + { + button.ToolTip = Loc.GetString("lathe-menu-tooltip-display", ("amount", sheetsToEject * VolumePerSheet), ("material", Loc.GetString(proto.Name))); + } + + Content.AddChild(button); + } + } +} diff --git a/Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml b/Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml new file mode 100644 index 00000000000000..be5eb1c7ef9504 --- /dev/null +++ b/Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml.cs new file mode 100644 index 00000000000000..4db470c1159f33 --- /dev/null +++ b/Content.Client/Lathe/UI/LatheMaterialsEjectionMenu.xaml.cs @@ -0,0 +1,74 @@ +using Content.Shared.Materials; +using Robust.Client.AutoGenerated; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Prototypes; +using System.Linq; + +namespace Content.Client.Lathe.UI; + +[GenerateTypedNameReferences] +public sealed partial class LatheMaterialsEjectionMenu : DefaultWindow +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + private readonly SpriteSystem _spriteSystem; + + public event Action? OnEjectPressed; + + public LatheMaterialsEjectionMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + _spriteSystem = _entityManager.EntitySysManager.GetEntitySystem(); + } + + public void PopulateMaterials(EntityUid lathe) + { + if (!_entityManager.TryGetComponent(lathe, out var materials)) + return; + + MaterialsList.DisposeAllChildren(); + + foreach (var (materialId, volume) in materials.Storage) + { + if (volume <= 0) + continue; + + if (!_prototypeManager.TryIndex(materialId, out MaterialPrototype? material)) + continue; + + var name = Loc.GetString(material.Name); + int volumePerSheet = 0; + int maxEjectableSheets = 0; + + if (material.StackEntity != null) + { + var proto = _prototypeManager.Index(material.StackEntity); + name = proto.Name; + + if (proto.TryGetComponent(out var composition)) + { + volumePerSheet = composition.MaterialComposition.FirstOrDefault(kvp => kvp.Key == materialId).Value; + maxEjectableSheets = (int) MathF.Floor(volume / volumePerSheet); + } + } + + var row = new LatheMaterialEjector(materialId, OnEjectPressed, volumePerSheet, maxEjectableSheets) + { + Icon = { Texture = _spriteSystem.Frame0(material.Icon) }, + ProductName = { Text = name } + }; + + MaterialsList.AddChild(row); + } + + if (MaterialsList.ChildCount == 0) + { + Close(); + } + } +} + diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml b/Content.Client/Lathe/UI/LatheMenu.xaml index 50f6fd99481f9f..a496fa9e50e11a 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml +++ b/Content.Client/Lathe/UI/LatheMenu.xaml @@ -1,9 +1,9 @@ - + SetSize="350 475"> + diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index 8162ec64ae4bd8..d8d0a8c0ab3d6d 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using System.Text; using Content.Client.Stylesheets; using Content.Shared.Lathe; @@ -22,6 +22,7 @@ public sealed partial class LatheMenu : DefaultWindow private readonly LatheSystem _lathe; public event Action? OnQueueButtonPressed; + public event Action? OnMaterialsEjectionButtonPressed; public event Action? OnServerListButtonPressed; public event Action? RecipeQueueAction; @@ -47,6 +48,7 @@ public LatheMenu(LatheBoundUserInterface owner) }; QueueButton.OnPressed += a => OnQueueButtonPressed?.Invoke(a); + MaterialsEjectionButton.OnPressed += a => OnMaterialsEjectionButtonPressed?.Invoke(a); ServerListButton.OnPressed += a => OnServerListButtonPressed?.Invoke(a); if (_entityManager.TryGetComponent(owner.Owner, out var latheComponent)) @@ -57,6 +59,11 @@ public LatheMenu(LatheBoundUserInterface owner) QueueButton.RemoveStyleClass(StyleBase.ButtonOpenRight); //QueueButton.AddStyleClass(StyleBase.ButtonSquare); } + + if (MaterialsEjectionButton != null && !latheComponent.CanEjectStoredMaterials) + { + MaterialsEjectionButton.Dispose(); + } } } @@ -69,14 +76,24 @@ public void PopulateMaterials(EntityUid lathe) foreach (var (id, amount) in materials.Storage) { + if (amount <= 0) + continue; + if (!_prototypeManager.TryIndex(id, out MaterialPrototype? material)) continue; + var name = Loc.GetString(material.Name); var mat = Loc.GetString("lathe-menu-material-display", ("material", name), ("amount", amount)); + Materials.AddItem(mat, _spriteSystem.Frame0(material.Icon), false); } + if (MaterialsEjectionButton != null) + { + MaterialsEjectionButton.Disabled = Materials.Count == 0; + } + if (Materials.Count == 0) { var noMaterialsMsg = Loc.GetString("lathe-menu-no-materials-message"); @@ -132,9 +149,7 @@ public void PopulateRecipes(EntityUid lathe) var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, component.MaterialUseMultiplier); - sb.Append(adjustedAmount); - sb.Append(' '); - sb.Append(Loc.GetString(proto.Name)); + sb.Append(Loc.GetString("lathe-menu-tooltip-display", ("amount", adjustedAmount), ("material", Loc.GetString(proto.Name)))); } var icon = prototype.Icon == null diff --git a/Content.Client/Lathe/UI/LatheQueueMenu.xaml b/Content.Client/Lathe/UI/LatheQueueMenu.xaml index 901af24a30ec2a..a92a0a18a17b0c 100644 --- a/Content.Client/Lathe/UI/LatheQueueMenu.xaml +++ b/Content.Client/Lathe/UI/LatheQueueMenu.xaml @@ -1,8 +1,8 @@ - + SetSize="350 475">