diff --git a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs
index 35094cecab..ab44d0f5a2 100644
--- a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs
+++ b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs
@@ -14,6 +14,9 @@ namespace Content.Client.Lathe.UI
[ViewVariables]
private LatheQueueMenu? _queueMenu;
+ [ViewVariables]
+ private LatheMaterialsEjectionMenu? _materialsEjectionMenu;
+
public LatheBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
@@ -24,6 +27,7 @@ namespace Content.Client.Lathe.UI
_menu = new LatheMenu(this);
_queueMenu = new LatheQueueMenu();
+ _materialsEjectionMenu = new LatheMaterialsEjectionMenu();
_menu.OnClose += Close;
@@ -34,15 +38,30 @@ namespace Content.Client.Lathe.UI
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 @@ namespace Content.Client.Lathe.UI
_menu?.PopulateMaterials(Owner);
_queueMenu?.PopulateList(msg.Queue);
_queueMenu?.SetInfo(msg.CurrentlyProducing);
+ _materialsEjectionMenu?.PopulateMaterials(Owner);
break;
}
}
@@ -70,6 +90,7 @@ namespace Content.Client.Lathe.UI
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 0000000000..713b49aa5c
--- /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 0000000000..090a189c71
--- /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 0000000000..be5eb1c7ef
--- /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 0000000000..4db470c115
--- /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 50f6fd9948..a496fa9e50 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 8162ec64ae..d8d0a8c0ab 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 sealed partial class LatheMenu : DefaultWindow
};
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 sealed partial class LatheMenu : DefaultWindow
QueueButton.RemoveStyleClass(StyleBase.ButtonOpenRight);
//QueueButton.AddStyleClass(StyleBase.ButtonSquare);
}
+
+ if (MaterialsEjectionButton != null && !latheComponent.CanEjectStoredMaterials)
+ {
+ MaterialsEjectionButton.Dispose();
+ }
}
}
@@ -69,14 +76,24 @@ public sealed partial class LatheMenu : DefaultWindow
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 sealed partial class LatheMenu : DefaultWindow
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 901af24a30..a92a0a18a1 100644
--- a/Content.Client/Lathe/UI/LatheQueueMenu.xaml
+++ b/Content.Client/Lathe/UI/LatheQueueMenu.xaml
@@ -1,8 +1,8 @@
-
+ SetSize="350 475">