diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs
index 3ef7f0ae73..a669a8da4c 100644
--- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs
+++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs
@@ -46,6 +46,8 @@ namespace Content.Client.Chemistry.UI
_window.CreateBottleButton.OnPressed += _ => SendMessage(
new ChemMasterOutputToBottleMessage(
(uint) _window.BottleDosage.Value, _window.LabelLine));
+ _window.BufferSortButton.OnPressed += _ => SendMessage(
+ new ChemMasterSortingTypeCycleMessage());
for (uint i = 0; i < _window.PillTypeButtons.Length; i++)
{
diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml
index b1f4f5917f..aca316f6b3 100644
--- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml
+++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml
@@ -34,6 +34,7 @@
+
diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
index 20c61f10cb..807ec4c1e7 100644
--- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
+++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
@@ -140,17 +140,17 @@ namespace Content.Client.Chemistry.UI
// Ensure the Panel Info is updated, including UI elements for Buffer Volume, Output Container and so on
UpdatePanelInfo(castState);
-
+
BufferCurrentVolume.Text = $" {castState.BufferCurrentVolume?.Int() ?? 0}u";
-
+
InputEjectButton.Disabled = castState.InputContainerInfo is null;
OutputEjectButton.Disabled = castState.OutputContainerInfo is null;
CreateBottleButton.Disabled = castState.OutputContainerInfo?.Reagents == null;
CreatePillButton.Disabled = castState.OutputContainerInfo?.Entities == null;
-
+
UpdateDosageFields(castState);
}
-
+
//assign default values for pill and bottle fields.
private void UpdateDosageFields(ChemMasterBoundUserInterfaceState castState)
{
@@ -162,8 +162,9 @@ namespace Content.Client.Chemistry.UI
var bufferVolume = castState.BufferCurrentVolume?.Int() ?? 0;
PillDosage.Value = (int)Math.Min(bufferVolume, castState.PillDosageLimit);
-
+
PillTypeButtons[castState.SelectedPillType].Pressed = true;
+
PillNumber.IsValid = x => x >= 0 && x <= pillNumberMax;
PillDosage.IsValid = x => x > 0 && x <= castState.PillDosageLimit;
BottleDosage.IsValid = x => x >= 0 && x <= bottleAmountMax;
@@ -213,6 +214,17 @@ namespace Content.Client.Chemistry.UI
BufferInfo.Children.Clear();
+ // This has to happen here due to people possibly
+ // setting sorting before putting any chemicals
+ BufferSortButton.Text = state.SortingType switch
+ {
+ ChemMasterSortingType.Alphabetical => Loc.GetString("chem-master-window-sort-type-alphabetical"),
+ ChemMasterSortingType.Quantity => Loc.GetString("chem-master-window-sort-type-quantity"),
+ ChemMasterSortingType.Latest => Loc.GetString("chem-master-window-sort-type-latest"),
+ _ => Loc.GetString("chem-master-window-sort-type-none")
+ };
+
+
if (!state.BufferReagents.Any())
{
BufferInfo.Children.Add(new Label { Text = Loc.GetString("chem-master-window-buffer-empty-text") });
@@ -235,19 +247,48 @@ namespace Content.Client.Chemistry.UI
};
bufferHBox.AddChild(bufferVol);
- // initialises rowCount to allow for striped rows
-
- var rowCount = 0;
+ // This sets up the needed data for sorting later in a list
+ // Its done this way to not repeat having to use same code twice (once for sorting
+ // and once for displaying)
+ var reagentList = new List<(ReagentId reagentId, string name, Color color, FixedPoint2 quantity)>();
foreach (var (reagent, quantity) in state.BufferReagents)
{
var reagentId = reagent;
_prototypeManager.TryIndex(reagentId.Prototype, out ReagentPrototype? proto);
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
var reagentColor = proto?.SubstanceColor ?? default(Color);
- BufferInfo.Children.Add(BuildReagentRow(reagentColor, rowCount++, name, reagentId, quantity, true, true));
+ reagentList.Add(new (reagentId, name, reagentColor, quantity));
+ }
+
+ // We sort here since we need sorted list to be filled first.
+ // You can easily add any new params you need to it.
+ switch (state.SortingType)
+ {
+ case ChemMasterSortingType.Alphabetical:
+ reagentList = reagentList.OrderBy(x => x.name).ToList();
+ break;
+
+ case ChemMasterSortingType.Quantity:
+ reagentList = reagentList.OrderByDescending(x => x.quantity).ToList();
+ break;
+ case ChemMasterSortingType.Latest:
+ reagentList = Enumerable.Reverse(reagentList).ToList();
+ break;
+
+ case ChemMasterSortingType.None:
+ default:
+ // This case is pointless but it is there for readability
+ break;
+ }
+
+ // initialises rowCount to allow for striped rows
+ var rowCount = 0;
+ foreach (var reagent in reagentList)
+ {
+ BufferInfo.Children.Add(BuildReagentRow(reagent.color, rowCount++, reagent.name, reagent.reagentId, reagent.quantity, true, true));
}
}
-
+
private void BuildContainerUI(Control control, ContainerInfo? info, bool addReagentButtons)
{
control.Children.Clear();
@@ -295,7 +336,7 @@ namespace Content.Client.Chemistry.UI
_prototypeManager.TryIndex(reagent.Reagent.Prototype, out ReagentPrototype? proto);
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
var reagentColor = proto?.SubstanceColor ?? default(Color);
-
+
control.Children.Add(BuildReagentRow(reagentColor, rowCount++, name, reagent.Reagent, reagent.Quantity, false, addReagentButtons));
}
}
@@ -315,7 +356,7 @@ namespace Content.Client.Chemistry.UI
}
//this calls the separated button builder, and stores the return to render after labels
var reagentButtonConstructors = CreateReagentTransferButtons(reagent, isBuffer, addReagentButtons);
-
+
// Create the row layout with the color panel
var rowContainer = new BoxContainer
{
@@ -358,7 +399,7 @@ namespace Content.Client.Chemistry.UI
Children = { rowContainer }
};
}
-
+
public string LabelLine
{
get => LabelLineEdit.Text;
diff --git a/Content.Server/Chemistry/Components/ChemMasterComponent.cs b/Content.Server/Chemistry/Components/ChemMasterComponent.cs
index 9578755ba7..0309d07ed9 100644
--- a/Content.Server/Chemistry/Components/ChemMasterComponent.cs
+++ b/Content.Server/Chemistry/Components/ChemMasterComponent.cs
@@ -18,6 +18,9 @@ namespace Content.Server.Chemistry.Components
[DataField("mode"), ViewVariables(VVAccess.ReadWrite)]
public ChemMasterMode Mode = ChemMasterMode.Transfer;
+ [DataField]
+ public ChemMasterSortingType SortingType = ChemMasterSortingType.None;
+
[DataField("pillDosageLimit", required: true), ViewVariables(VVAccess.ReadWrite)]
public uint PillDosageLimit;
diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs
index c733c7215e..dd97bfa8f6 100644
--- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs
+++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs
@@ -53,6 +53,7 @@ namespace Content.Server.Chemistry.EntitySystems
SubscribeLocalEvent(SubscribeUpdateUiState);
SubscribeLocalEvent(OnSetModeMessage);
+ SubscribeLocalEvent(OnCycleSortingTypeMessage);
SubscribeLocalEvent(OnSetPillTypeMessage);
SubscribeLocalEvent(OnReagentButtonMessage);
SubscribeLocalEvent(OnCreatePillsMessage);
@@ -76,7 +77,7 @@ namespace Content.Server.Chemistry.EntitySystems
var bufferCurrentVolume = bufferSolution.Volume;
var state = new ChemMasterBoundUserInterfaceState(
- chemMaster.Mode, BuildInputContainerInfo(inputContainer), BuildOutputContainerInfo(outputContainer),
+ chemMaster.Mode, chemMaster.SortingType, BuildInputContainerInfo(inputContainer), BuildOutputContainerInfo(outputContainer),
bufferReagents, bufferCurrentVolume, chemMaster.PillType, chemMaster.PillDosageLimit, updateLabel);
_userInterfaceSystem.SetUiState(owner, ChemMasterUiKey.Key, state);
@@ -93,6 +94,15 @@ namespace Content.Server.Chemistry.EntitySystems
ClickSound(chemMaster);
}
+ private void OnCycleSortingTypeMessage(Entity chemMaster, ref ChemMasterSortingTypeCycleMessage message)
+ {
+ chemMaster.Comp.SortingType++;
+ if (chemMaster.Comp.SortingType > ChemMasterSortingType.Latest)
+ chemMaster.Comp.SortingType = ChemMasterSortingType.None;
+ UpdateUiState(chemMaster);
+ ClickSound(chemMaster);
+ }
+
private void OnSetPillTypeMessage(Entity chemMaster, ref ChemMasterSetPillTypeMessage message)
{
// Ensure valid pill type. There are 20 pills selectable, 0-19.
diff --git a/Content.Shared/Chemistry/SharedChemMaster.cs b/Content.Shared/Chemistry/SharedChemMaster.cs
index 762131d761..67bd9a0d63 100644
--- a/Content.Shared/Chemistry/SharedChemMaster.cs
+++ b/Content.Shared/Chemistry/SharedChemMaster.cs
@@ -89,6 +89,18 @@ namespace Content.Shared.Chemistry
Discard,
}
+ public enum ChemMasterSortingType : byte
+ {
+ None = 0,
+ Alphabetical = 1,
+ Quantity = 2,
+ Latest = 3,
+ }
+
+ [Serializable, NetSerializable]
+ public sealed class ChemMasterSortingTypeCycleMessage : BoundUserInterfaceMessage;
+
+
public enum ChemMasterReagentAmount
{
U1 = 1,
@@ -160,6 +172,8 @@ namespace Content.Shared.Chemistry
public readonly ChemMasterMode Mode;
+ public readonly ChemMasterSortingType SortingType;
+
public readonly FixedPoint2? BufferCurrentVolume;
public readonly uint SelectedPillType;
@@ -168,7 +182,7 @@ namespace Content.Shared.Chemistry
public readonly bool UpdateLabel;
public ChemMasterBoundUserInterfaceState(
- ChemMasterMode mode, ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo,
+ ChemMasterMode mode, ChemMasterSortingType sortingType, ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo,
IReadOnlyList bufferReagents, FixedPoint2 bufferCurrentVolume,
uint selectedPillType, uint pillDosageLimit, bool updateLabel)
{
@@ -176,6 +190,7 @@ namespace Content.Shared.Chemistry
OutputContainerInfo = outputContainerInfo;
BufferReagents = bufferReagents;
Mode = mode;
+ SortingType = sortingType;
BufferCurrentVolume = bufferCurrentVolume;
SelectedPillType = selectedPillType;
PillDosageLimit = pillDosageLimit;
diff --git a/Resources/Locale/en-US/chemistry/components/chem-master-component.ftl b/Resources/Locale/en-US/chemistry/components/chem-master-component.ftl
index 51110f12c4..c000811e77 100644
--- a/Resources/Locale/en-US/chemistry/components/chem-master-component.ftl
+++ b/Resources/Locale/en-US/chemistry/components/chem-master-component.ftl
@@ -29,3 +29,7 @@ chem-master-window-dose-label = Dose (u):
chem-master-window-create-button = Create
chem-master-window-bottles-label = Bottles:
chem-master-window-unknown-reagent-text = Unknown reagent
+chem-master-window-sort-type-none = Sort by: Oldest First
+chem-master-window-sort-type-alphabetical = Sort by: Alphabetical
+chem-master-window-sort-type-quantity = Sort by: Quantity
+chem-master-window-sort-type-latest = Sort by: Recent First