diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs
index 793c4694832..f429511d318 100644
--- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs
+++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs
@@ -10,15 +10,11 @@ namespace Content.Client.Chemistry.UI
/// Initializes a and updates it when new server messages are received.
///
[UsedImplicitly]
- public sealed class ChemMasterBoundUserInterface : BoundUserInterface
+ public sealed class ChemMasterBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
{
[ViewVariables]
private ChemMasterWindow? _window;
- public ChemMasterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
- {
- }
-
///
/// Called each time a chem master UI instance is opened. Generates the window and fills it with
/// relevant info. Sets the actions for static buttons.
@@ -49,7 +45,11 @@ protected override void Open()
_window.PillTypeButtons[i].OnPressed += _ => SendMessage(new ChemMasterSetPillTypeMessage(pillType));
}
- _window.OnReagentButtonPressed += (args, button) => SendMessage(new ChemMasterReagentAmountButtonMessage(button.Id, button.Amount, button.IsBuffer));
+ _window.OnReagentButtonPressed += (_, button, amount) => SendMessage(new ChemMasterReagentAmountButtonMessage(button.Id, amount, button.IsBuffer));
+ _window.OnSortMethodChanged += sortMethod => SendMessage(new ChemMasterSortMethodUpdated(sortMethod));
+ _window.OnTransferAmountChanged += amount => SendMessage(new ChemMasterTransferringAmountUpdated(amount));
+
+
}
///
@@ -64,7 +64,6 @@ protected override void UpdateState(BoundUserInterfaceState state)
base.UpdateState(state);
var castState = (ChemMasterBoundUserInterfaceState) state;
-
_window?.UpdateState(castState); // Update window state
}
}
diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml
index 04ee58f10c2..788b018d4d4 100644
--- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml
+++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml
@@ -2,7 +2,7 @@
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
- MinSize="620 670"
+ MinSize="500 770"
Title="{Loc 'chem-master-bound-user-interface-title'}">
@@ -10,7 +10,9 @@
-
+
+
+
@@ -30,7 +32,13 @@
-
+
+
+
+
+
+
+
@@ -52,6 +60,8 @@
+
+
diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
index e731f3a1145..966b979fae6 100644
--- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
+++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
@@ -24,9 +24,18 @@ namespace Content.Client.Chemistry.UI
public sealed partial class ChemMasterWindow : FancyWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- public event Action? OnReagentButtonPressed;
+ public event Action? OnReagentButtonPressed;
+ public event Action? OnSortMethodChanged;
+ public event Action? OnTransferAmountChanged;
public readonly Button[] PillTypeButtons;
+ private Dictionary _reagents;
+ private const string TransferringAmountColor = "#ffa500";
+ private ReagentSortMethod _currentSortMethod = ReagentSortMethod.Alphabetical;
+ private ChemMasterBoundUserInterfaceState? _lastState;
+ private int _transferAmount = 50;
+
+
private const string PillsRsiPath = "/Textures/Objects/Specific/Chemistry/pills.rsi";
///
@@ -38,6 +47,14 @@ public ChemMasterWindow()
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
+ _reagents = new();
+
+ InputAmountLineEdit.OnTextEntered += SetAmount;
+ InputAmountLineEdit.OnFocusExit += SetAmount;
+
+ OutputAmountLineEdit.OnTextEntered += SetAmount;
+ OutputAmountLineEdit.OnFocusExit += SetAmount;
+
// Pill type selection buttons, in total there are 20 pills.
// Pill rsi file should have states named as pill1, pill2, and so on.
var resourcePath = new ResPath(PillsRsiPath);
@@ -87,44 +104,96 @@ public ChemMasterWindow()
Tabs.SetTabTitle(0, Loc.GetString("chem-master-window-input-tab"));
Tabs.SetTabTitle(1, Loc.GetString("chem-master-window-output-tab"));
+
+ SortMethod.AddItem(
+ Loc.GetString("chem-master-window-sort-method-Alphabetical-text"),
+ (int) ReagentSortMethod.Alphabetical);
+ SortMethod.AddItem(Loc.GetString("chem-master-window-sort-method-Amount-text"), (int) ReagentSortMethod.Amount);
+ SortMethod.AddItem(Loc.GetString("chem-master-window-sort-method-Time-text"), (int) ReagentSortMethod.Time);
+ SortMethod.OnItemSelected += HandleChildPressed;
+ }
+
+ private void HandleSortMethodChange(int newSortMethod)
+ {
+ if (newSortMethod == (int) _currentSortMethod)
+ return;
+
+ _currentSortMethod = (ReagentSortMethod) newSortMethod;
+ SortMethod.SelectId(newSortMethod);
+ SortUpdated();
+ }
+
+ private void HandleChildPressed(OptionButton.ItemSelectedEventArgs args)
+ {
+ HandleSortMethodChange(args.Id);
+ OnSortMethodChanged?.Invoke(args.Id);
+ }
+
+ private void SortUpdated()
+ {
+ if (_lastState == null)
+ return;
+
+ UpdatePanelInfo(_lastState);
}
- private ReagentButton MakeReagentButton(string text, ChemMasterReagentAmount amount, ReagentId id, bool isBuffer, string styleClass)
+ private bool ValidateAmount(string newText)
{
- var reagentTransferButton = new ReagentButton(text, amount, id, isBuffer, styleClass);
+ if (string.IsNullOrWhiteSpace(newText) || !int.TryParse(newText, out int amount))
+ {
+ InputAmountLineEdit.SetText(string.Empty);
+ OutputAmountLineEdit.SetText(string.Empty);
+ return false;
+ }
+
+ _transferAmount = amount;
+ OnTransferAmountChanged?.Invoke(amount);
+ return true;
+ }
+
+ private void SetAmount(LineEdit.LineEditEventArgs args) =>
+ SetAmountText(args.Text);
+
+ private void SetAmountText(string newText)
+ {
+ if (newText == _transferAmount.ToString() || !ValidateAmount(newText))
+ return;
+
+ var localizedAmount = Loc.GetString(
+ "chem-master-window-transferring-label",
+ ("quantity", newText),
+ ("color", TransferringAmountColor));
+
+ InputAmountLabel.Text = localizedAmount;
+ OutputAmountLabel.Text = localizedAmount;
+
+ InputAmountLineEdit.SetText(string.Empty);
+ OutputAmountLineEdit.SetText(string.Empty);
+ }
+
+ private ReagentButton MakeReagentButton(string text, ReagentId id, bool isBuffer)
+ {
+ var reagentTransferButton = new ReagentButton(text, id, isBuffer);
reagentTransferButton.OnPressed += args
- => OnReagentButtonPressed?.Invoke(args, reagentTransferButton);
+ => OnReagentButtonPressed?.Invoke(args, reagentTransferButton, _transferAmount);
return reagentTransferButton;
}
///
/// Conditionally generates a set of reagent buttons based on the supplied boolean argument.
/// This was moved outside of BuildReagentRow to facilitate conditional logic, stops indentation depth getting out of hand as well.
///
- private List CreateReagentTransferButtons(ReagentId reagent, bool isBuffer, bool addReagentButtons)
+ private ReagentButton? CreateReagentTransferButton(ReagentId reagent, bool isBuffer, bool addReagentButtons)
{
if (!addReagentButtons)
- return new List(); // Return an empty list if reagentTransferButton creation is disabled.
+ return null; // Return an empty list if reagentTransferButton creation is disabled.
- var buttonConfigs = new (string text, ChemMasterReagentAmount amount, string styleClass)[]
- {
- ("1", ChemMasterReagentAmount.U1, StyleBase.ButtonOpenBoth),
- ("5", ChemMasterReagentAmount.U5, StyleBase.ButtonOpenBoth),
- ("10", ChemMasterReagentAmount.U10, StyleBase.ButtonOpenBoth),
- ("25", ChemMasterReagentAmount.U25, StyleBase.ButtonOpenBoth),
- ("50", ChemMasterReagentAmount.U50, StyleBase.ButtonOpenBoth),
- ("100", ChemMasterReagentAmount.U100, StyleBase.ButtonOpenBoth),
- (Loc.GetString("chem-master-window-buffer-all-amount"), ChemMasterReagentAmount.All, StyleBase.ButtonOpenLeft),
- };
-
- var buttons = new List();
-
- foreach (var (text, amount, styleClass) in buttonConfigs)
- {
- var reagentTransferButton = MakeReagentButton(text, amount, reagent, isBuffer, styleClass);
- buttons.Add(reagentTransferButton);
- }
+ var reagentTransferButton = MakeReagentButton(
+ Loc.GetString("chem-master-window-transfer-button"),
+ reagent,
+ isBuffer
+ );
- return buttons;
+ return reagentTransferButton;
}
///
@@ -138,19 +207,23 @@ public void UpdateState(BoundUserInterfaceState state)
if (castState.UpdateLabel)
LabelLine = GenerateLabel(castState);
+ _lastState = castState;
+
// Ensure the Panel Info is updated, including UI elements for Buffer Volume, Output Container and so on
UpdatePanelInfo(castState);
-
+ HandleSortMethodChange(castState.SortMethod);
+ SetAmountText(castState.TransferringAmount.ToString());
+
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,7 +235,7 @@ private void UpdateDosageFields(ChemMasterBoundUserInterfaceState castState)
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;
@@ -233,18 +306,60 @@ private void UpdatePanelInfo(ChemMasterBoundUserInterfaceState state)
bufferHBox.AddChild(bufferVol);
// initialises rowCount to allow for striped rows
-
var rowCount = 0;
- foreach (var (reagent, quantity) in state.BufferReagents)
+ var bufferReagents = state.BufferReagents.OrderBy(x => x.Reagent.Prototype);
+
+ if (_currentSortMethod == ReagentSortMethod.Amount)
+ bufferReagents = bufferReagents.OrderByDescending(x => x.Quantity);
+
+ if (_currentSortMethod == ReagentSortMethod.Time)
+ {
+ bufferReagents = bufferReagents.OrderByDescending(
+ x =>
+ {
+ var exists = _reagents.TryGetValue(x.Reagent.Prototype, out var reagent);
+ return exists && reagent != null ? reagent.TimeAdded : DateTimeOffset.UtcNow;
+ });
+ }
+
+ var bufferAsNames = bufferReagents.Select(r => r.Reagent.Prototype).ToHashSet();
+ var hashSetCachedReagents = _reagents.Keys.ToHashSet();
+ hashSetCachedReagents.ExceptWith(bufferAsNames);
+
+ foreach (var missing in hashSetCachedReagents)
+ _reagents.Remove(missing);
+
+ foreach (var (reagent, quantity) in 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));
+
+ var exists = _reagents.TryGetValue(reagent.Prototype, out var reagentCached);
+
+ if (!exists)
+ {
+ reagentCached = new()
+ {
+ Id = reagentId,
+ Quantity = quantity,
+ TimeAdded = reagentCached?.TimeAdded ?? DateTimeOffset.UtcNow
+ };
+
+ _reagents.Add(reagentId.Prototype, reagentCached);
+ }
+ else
+ {
+ reagentCached!.Quantity = quantity;
+ reagentCached!.Id = reagentId;
+
+ _reagents[reagentId.Prototype] = reagentCached;
+ }
}
}
-
+
private void BuildContainerUI(Control control, ContainerInfo? info, bool addReagentButtons)
{
control.Children.Clear();
@@ -292,7 +407,7 @@ private void BuildContainerUI(Control control, ContainerInfo? info, bool addReag
_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));
}
}
@@ -311,8 +426,8 @@ private Control BuildReagentRow(Color reagentColor, int rowCount, string name, R
reagentColor = currentRowColor;
}
//this calls the separated button builder, and stores the return to render after labels
- var reagentButtonConstructors = CreateReagentTransferButtons(reagent, isBuffer, addReagentButtons);
-
+ var reagentButtonConstructor = CreateReagentTransferButton(reagent, isBuffer, addReagentButtons);
+
// Create the row layout with the color panel
var rowContainer = new BoxContainer
{
@@ -343,11 +458,9 @@ private Control BuildReagentRow(Color reagentColor, int rowCount, string name, R
}
};
- // Add the reagent buttons after the color panel
- foreach (var reagentTransferButton in reagentButtonConstructors)
- {
- rowContainer.AddChild(reagentTransferButton);
- }
+ if (reagentButtonConstructor != null)
+ rowContainer.AddChild(reagentButtonConstructor);
+
//Apply panencontainer to allow for striped rows
return new PanelContainer
{
@@ -355,7 +468,7 @@ private Control BuildReagentRow(Color reagentColor, int rowCount, string name, R
Children = { rowContainer }
};
}
-
+
public string LabelLine
{
get => LabelLineEdit.Text;
@@ -365,16 +478,28 @@ public string LabelLine
public sealed class ReagentButton : Button
{
- public ChemMasterReagentAmount Amount { get; set; }
public bool IsBuffer = true;
public ReagentId Id { get; set; }
- public ReagentButton(string text, ChemMasterReagentAmount amount, ReagentId id, bool isBuffer, string styleClass)
+ public ReagentButton(string text, ReagentId id, bool isBuffer)
{
- AddStyleClass(styleClass);
+ AddStyleClass(StyleBase.ButtonOpenLeft);
Text = text;
- Amount = amount;
Id = id;
IsBuffer = isBuffer;
}
}
+
+ public sealed class ReagentCached
+ {
+ public ReagentId Id { get; set; }
+ public DateTimeOffset TimeAdded { get; set; }
+ public FixedPoint2 Quantity { get; set; }
+ }
+
+ public enum ReagentSortMethod
+ {
+ Time,
+ Alphabetical,
+ Amount
+ }
}
diff --git a/Content.Server/Chemistry/Components/ChemMasterComponent.cs b/Content.Server/Chemistry/Components/ChemMasterComponent.cs
index 08e26a5392e..a3abc3b98e7 100644
--- a/Content.Server/Chemistry/Components/ChemMasterComponent.cs
+++ b/Content.Server/Chemistry/Components/ChemMasterComponent.cs
@@ -20,5 +20,11 @@ public sealed partial class ChemMasterComponent : Component
[DataField("clickSound"), ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg");
+
+ [DataField]
+ public int SortMethod;
+
+ [DataField]
+ public int TransferringAmount;
}
}
diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs
index 567fafb82ee..fd5833c036d 100644
--- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs
+++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs
@@ -56,12 +56,12 @@ public override void Initialize()
SubscribeLocalEvent(OnReagentButtonMessage);
SubscribeLocalEvent(OnCreatePillsMessage);
SubscribeLocalEvent(OnOutputToBottleMessage);
+ SubscribeLocalEvent(OnSortMethodUpdated);
+ SubscribeLocalEvent(OnTransferringAmountUpdated);
}
- private void SubscribeUpdateUiState(Entity ent, ref T ev)
- {
+ private void SubscribeUpdateUiState(Entity ent, ref T ev) =>
UpdateUiState(ent);
- }
private void UpdateUiState(Entity ent, bool updateLabel = false)
{
@@ -75,8 +75,15 @@ private void UpdateUiState(Entity ent, bool updateLabel = f
var bufferCurrentVolume = bufferSolution.Volume;
var state = new ChemMasterBoundUserInterfaceState(
- BuildInputContainerInfo(inputContainer), BuildOutputContainerInfo(outputContainer),
- bufferReagents, bufferCurrentVolume, chemMaster.PillType, chemMaster.PillDosageLimit, updateLabel);
+ BuildInputContainerInfo(inputContainer),
+ BuildOutputContainerInfo(outputContainer),
+ bufferReagents,
+ bufferCurrentVolume,
+ chemMaster.PillType,
+ chemMaster.PillDosageLimit,
+ updateLabel,
+ ent.Comp.SortMethod,
+ ent.Comp.TransferringAmount);
_userInterfaceSystem.SetUiState(owner, ChemMasterUiKey.Key, state);
}
@@ -94,11 +101,7 @@ private void OnSetPillTypeMessage(Entity chemMaster, ref Ch
private void OnReagentButtonMessage(Entity chemMaster, ref ChemMasterReagentAmountButtonMessage message)
{
- // Ensure the amount corresponds to one of the reagent amount buttons.
- if (!Enum.IsDefined(typeof(ChemMasterReagentAmount), message.Amount))
- return;
-
- TransferReagents(chemMaster, message.ReagentId, message.Amount.GetFixedPoint(), message.FromBuffer);
+ TransferReagents(chemMaster, message.ReagentId, chemMaster.Comp.TransferringAmount, message.FromBuffer);
ClickSound(chemMaster);
}
@@ -300,5 +303,17 @@ private static ContainerInfo BuildContainerInfo(string name, Solution solution)
Reagents = solution.Contents
};
}
+
+ private void OnSortMethodUpdated(EntityUid uid, ChemMasterComponent chemMaster, ChemMasterSortMethodUpdated args)
+ {
+ chemMaster.SortMethod = args.SortMethod;
+ UpdateUiState((uid, chemMaster));
+ }
+
+ private void OnTransferringAmountUpdated(EntityUid uid, ChemMasterComponent chemMaster, ChemMasterTransferringAmountUpdated args)
+ {
+ chemMaster.TransferringAmount = args.TransferringAmount;
+ UpdateUiState((uid, chemMaster));
+ }
}
}
diff --git a/Content.Shared/Chemistry/SharedChemMaster.cs b/Content.Shared/Chemistry/SharedChemMaster.cs
index f1cbc72bb78..4ef80550a30 100644
--- a/Content.Shared/Chemistry/SharedChemMaster.cs
+++ b/Content.Shared/Chemistry/SharedChemMaster.cs
@@ -33,10 +33,10 @@ public ChemMasterSetPillTypeMessage(uint pillType)
public sealed class ChemMasterReagentAmountButtonMessage : BoundUserInterfaceMessage
{
public readonly ReagentId ReagentId;
- public readonly ChemMasterReagentAmount Amount;
+ public readonly int Amount;
public readonly bool FromBuffer;
- public ChemMasterReagentAmountButtonMessage(ReagentId reagentId, ChemMasterReagentAmount amount, bool fromBuffer)
+ public ChemMasterReagentAmountButtonMessage(ReagentId reagentId, int amount, bool fromBuffer)
{
ReagentId = reagentId;
Amount = amount;
@@ -72,6 +72,24 @@ public ChemMasterOutputToBottleMessage(uint dosage, string label)
}
}
+ [Serializable, NetSerializable]
+ public sealed class ChemMasterSortMethodUpdated(int sortMethod) : BoundUserInterfaceMessage
+ {
+ public readonly int SortMethod = sortMethod;
+ }
+
+ [Serializable, NetSerializable]
+ public sealed class ChemMasterTransferringAmountUpdated(int transferringAmount) : BoundUserInterfaceMessage
+ {
+ public readonly int TransferringAmount = transferringAmount;
+ }
+
+ public enum ChemMasterMode
+ {
+ Transfer,
+ Discard,
+ }
+
public enum ChemMasterReagentAmount
{
U1 = 1,
@@ -148,10 +166,13 @@ public sealed class ChemMasterBoundUserInterfaceState : BoundUserInterfaceState
public readonly bool UpdateLabel;
+ public readonly int SortMethod;
+ public readonly int TransferringAmount;
+
public ChemMasterBoundUserInterfaceState(
ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo,
IReadOnlyList bufferReagents, FixedPoint2 bufferCurrentVolume,
- uint selectedPillType, uint pillDosageLimit, bool updateLabel)
+ uint selectedPillType, uint pillDosageLimit, bool updateLabel, int sortMethod, int transferringAmount)
{
InputContainerInfo = inputContainerInfo;
OutputContainerInfo = outputContainerInfo;
@@ -160,6 +181,8 @@ public ChemMasterBoundUserInterfaceState(
SelectedPillType = selectedPillType;
PillDosageLimit = pillDosageLimit;
UpdateLabel = updateLabel;
+ SortMethod = sortMethod;
+ TransferringAmount = transferringAmount;
}
}
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 873ec7104ec..aff0cfac66c 100644
--- a/Resources/Locale/en-US/chemistry/components/chem-master-component.ftl
+++ b/Resources/Locale/en-US/chemistry/components/chem-master-component.ftl
@@ -11,6 +11,7 @@ chem-master-bound-user-interface-title = ChemMaster 4000
chem-master-window-input-tab = Input
chem-master-window-output-tab = Output
chem-master-window-container-label = Container
+chem-master-window-amount-placeholder = Transfer Amount
chem-master-window-eject-button = Eject
chem-master-window-no-container-loaded-text = No container loaded.
chem-master-window-buffer-text = Buffer
@@ -18,6 +19,15 @@ chem-master-window-buffer-label = buffer:
chem-master-window-buffer-all-amount = All
chem-master-window-buffer-empty-text = Buffer empty.
chem-master-window-buffer-low-text = Not enough solution in buffer
+chem-master-window-transfer-button = Transfer
+chem-master-window-sort-method-tooltip = Choose your buffer's sort method.
+chem-master-window-sort-method-Time-text = Last Added
+chem-master-window-sort-method-Alphabetical-text = Alphabetical Order
+chem-master-window-sort-method-Amount-text = Quantity
+chem-master-window-transferring-label = Transferring: [color={$color}]{$quantity}[/color]
+chem-master-window-transferring-default-label = Transferring: [color=#ffa500]50[/color]
+chem-master-window-reagent-move-button = Move
+chem-master-window-discard-button = Discard
chem-master-window-packaging-text = Packaging
chem-master-current-text-label = Label:
chem-master-window-pills-label = Pills: