From 7b5b033c57678667ae9d5dd5c756f83602587526 Mon Sep 17 00:00:00 2001 From: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> Date: Sat, 18 Jan 2025 16:03:16 -0400 Subject: [PATCH 01/20] ChemMaster+ (#1585) Changes how the ChemMaster works: 1. Removes the amount buttons and instead uses a textbox that resets whenever a value is entered or focus ends. 2. Shrinks the ChemMaster again. 3. Adds sorting options, including for quantity, last added, and a sort option for the (default) alphabetical order. 4. Sorting options save via the ChemMaster itself, not per-user. Video showcase: https://discord.com/channels/1218698320155906090/1218698321053356060/1330129166384894046 --- :cl: - add: Added sorting options to the ChemMaster. - add: Added the ability to input custom amounts into the ChemMaster via a textbox that resets on change. - tweak: The width of the ChemMaster UI has been lowered. - remove: Removed quantity buttons from the ChemMaster. --------- Co-authored-by: VMSolidus --- .../UI/ChemMasterBoundUserInterface.cs | 13 +- .../Chemistry/UI/ChemMasterWindow.xaml | 16 +- .../Chemistry/UI/ChemMasterWindow.xaml.cs | 224 +++++++++++++++--- .../Components/ChemMasterComponent.cs | 6 + .../EntitySystems/ChemMasterSystem.cs | 46 +++- Content.Shared/Chemistry/SharedChemMaster.cs | 29 ++- .../components/chem-master-component.ftl | 10 + 7 files changed, 284 insertions(+), 60 deletions(-) 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 @@ public readonly IReadOnlyList PillBufferReagents = pillBufferReagents; - public readonly ChemMasterMode Mode = mode; - public readonly FixedPoint2? BufferCurrentVolume = bufferCurrentVolume; public readonly FixedPoint2? PillBufferCurrentVolume = pillBufferCurrentVolume; - + public readonly uint SelectedPillType = selectedPillType; public readonly uint PillDosageLimit = pillDosageLimit; @@ -168,22 +165,6 @@ public sealed class ChemMasterBoundUserInterfaceState( public readonly int SortMethod = sortMethod; public readonly int TransferringAmount = transferringAmount; - - public ChemMasterBoundUserInterfaceState( - ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo, - IReadOnlyList bufferReagents, FixedPoint2 bufferCurrentVolume, - uint selectedPillType, uint pillDosageLimit, bool updateLabel, int sortMethod, int transferringAmount) - { - InputContainerInfo = inputContainerInfo; - OutputContainerInfo = outputContainerInfo; - BufferReagents = bufferReagents; - BufferCurrentVolume = bufferCurrentVolume; - SelectedPillType = selectedPillType; - PillDosageLimit = pillDosageLimit; - UpdateLabel = updateLabel; - SortMethod = sortMethod; - TransferringAmount = transferringAmount; - } } [Serializable, NetSerializable] From 1d38c0cc118eddd3df9d9c9a0d850c0028ddbdf6 Mon Sep 17 00:00:00 2001 From: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> Date: Sun, 26 Jan 2025 14:16:20 -0400 Subject: [PATCH 05/20] Fix Chemmaster Two (#1667) simplify this shitcode i borked it last time, sorry --------- Signed-off-by: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> Co-authored-by: VMSolidus --- .../Chemistry/UI/ChemMasterWindow.xaml.cs | 107 ++---------------- 1 file changed, 10 insertions(+), 97 deletions(-) diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs index 4db8e162b4c..e547e104125 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs @@ -30,7 +30,6 @@ public sealed partial class ChemMasterWindow : FancyWindow public event Action? OnTransferAmountChanged; public readonly Button[] PillTypeButtons; - private Dictionary _reagents; private const string TransferringAmountColor = "#ffffff"; private ReagentSortMethod _currentSortMethod = ReagentSortMethod.Alphabetical; private ChemMasterBoundUserInterfaceState? _lastState; @@ -47,7 +46,6 @@ public ChemMasterWindow() RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _reagents = new(); AmountLabel.HorizontalAlignment = HAlignment.Center; AmountLineEdit.OnTextEntered += (args) => SetAmountText(args.Text); AmountLineEdit.OnFocusExit += (args) => SetAmountText(args.Text); @@ -335,61 +333,12 @@ private void BuildBufferInfo(ChemMasterBoundUserInterfaceState state) }; bufferHBox.AddChild(bufferVol); - // initialises rowCount to allow for striped rows - var rowCount = 0; 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; - } - } + HandleBuffer(_currentSortMethod == ReagentSortMethod.Time ? state.BufferReagents : bufferReagents, false); } private void BuildPillBufferInfo(ChemMasterBoundUserInterfaceState state) @@ -417,58 +366,29 @@ private void BuildPillBufferInfo(ChemMasterBoundUserInterfaceState state) }; bufferHBox.AddChild(bufferVol); - // initialises rowCount to allow for striped rows - var rowCount = 0; var bufferReagents = state.PillBufferReagents.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); + HandleBuffer(_currentSortMethod == ReagentSortMethod.Time ? state.PillBufferReagents : bufferReagents, true); + } + private void HandleBuffer(IEnumerable reagents, bool pillBuffer) + { 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); - PillBufferInfo.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); - } + if (pillBuffer) + PillBufferInfo.Children.Add( + BuildReagentRow(reagentColor, rowCount++, name, reagentId, quantity, true, true)); else - { - reagentCached!.Quantity = quantity; - reagentCached!.Id = reagentId; - - _reagents[reagentId.Prototype] = reagentCached; - } + BufferInfo.Children.Add( + BuildReagentRow(reagentColor, rowCount++, name, reagentId, quantity, true, true)); } } @@ -601,13 +521,6 @@ public ReagentButton(string text, ReagentId id, bool isBuffer) } } - public sealed class ReagentCached - { - public ReagentId Id { get; set; } - public DateTimeOffset TimeAdded { get; set; } - public FixedPoint2 Quantity { get; set; } - } - public enum ReagentSortMethod { Time, From 7ec15092a86be00ad37af608be03973b99dea772 Mon Sep 17 00:00:00 2001 From: sleepyyapril Date: Mon, 27 Jan 2025 02:28:20 -0400 Subject: [PATCH 06/20] Use separate counts for the separate buffers. --- Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs index e547e104125..3342df73207 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs @@ -376,7 +376,10 @@ private void BuildPillBufferInfo(ChemMasterBoundUserInterfaceState state) private void HandleBuffer(IEnumerable reagents, bool pillBuffer) { - foreach (var (reagent, quantity) in bufferReagents) + var rowCount = 0; + var pillRowCount = 0; + + foreach (var (reagent, quantity) in reagents) { var reagentId = reagent; _prototypeManager.TryIndex(reagentId.Prototype, out ReagentPrototype? proto); @@ -384,11 +387,15 @@ private void HandleBuffer(IEnumerable reagents, bool pillBuffer var reagentColor = proto?.SubstanceColor ?? default(Color); if (pillBuffer) + { PillBufferInfo.Children.Add( - BuildReagentRow(reagentColor, rowCount++, name, reagentId, quantity, true, true)); + BuildReagentRow(reagentColor, pillRowCount++, name, reagentId, quantity, true, true)); + } else + { BufferInfo.Children.Add( BuildReagentRow(reagentColor, rowCount++, name, reagentId, quantity, true, true)); + } } } From 90997dbfa12838eb818e92e09ba40fe5d5635c0e Mon Sep 17 00:00:00 2001 From: sleepyyapril Date: Mon, 27 Jan 2025 02:49:11 -0400 Subject: [PATCH 07/20] You want comments? I'll give you comments. --- .../UI/ChemMasterBoundUserInterface.cs | 8 +- .../Chemistry/UI/ChemMasterWindow.xaml.cs | 107 ++++++++++-------- 2 files changed, 65 insertions(+), 50 deletions(-) diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs index 192f367656a..08e3125523f 100644 --- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs @@ -10,7 +10,7 @@ namespace Content.Client.Chemistry.UI /// Initializes a and updates it when new server messages are received. /// [UsedImplicitly] - public sealed class ChemMasterBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) + public sealed class ChemMasterBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) // Delta-v { [ViewVariables] private ChemMasterWindow? _window; @@ -43,9 +43,9 @@ protected override void Open() _window.PillTypeButtons[i].OnPressed += _ => SendMessage(new ChemMasterSetPillTypeMessage(pillType)); } - _window.OnReagentButtonPressed += (_, button, amount, isOutput) => SendMessage(new ChemMasterReagentAmountButtonMessage(button.Id, amount, button.IsBuffer, isOutput)); - _window.OnSortMethodChanged += sortMethod => SendMessage(new ChemMasterSortMethodUpdated(sortMethod)); - _window.OnTransferAmountChanged += amount => SendMessage(new ChemMasterTransferringAmountUpdated(amount)); + _window.OnReagentButtonPressed += (_, button, amount, isOutput) => SendMessage(new ChemMasterReagentAmountButtonMessage(button.Id, amount, button.IsBuffer, isOutput)); // Delta-v + _window.OnSortMethodChanged += sortMethod => SendMessage(new ChemMasterSortMethodUpdated(sortMethod)); // Delta-v + _window.OnTransferAmountChanged += amount => SendMessage(new ChemMasterTransferringAmountUpdated(amount)); // Delta-v } /// diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs index 3342df73207..9e3103133e2 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs @@ -24,16 +24,16 @@ namespace Content.Client.Chemistry.UI public sealed partial class ChemMasterWindow : FancyWindow { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - public event Action? OnReagentButtonPressed; - public event Action? OnAmountButtonPressed; - public event Action? OnSortMethodChanged; - public event Action? OnTransferAmountChanged; + public event Action? OnReagentButtonPressed; // Delta-v + public event Action? OnAmountButtonPressed; // Delta-v + public event Action? OnSortMethodChanged; // Delta-v + public event Action? OnTransferAmountChanged; // Delta-v public readonly Button[] PillTypeButtons; - private const string TransferringAmountColor = "#ffffff"; - private ReagentSortMethod _currentSortMethod = ReagentSortMethod.Alphabetical; - private ChemMasterBoundUserInterfaceState? _lastState; - private int _transferAmount = 50; + private const string TransferringAmountColor = "#ffffff"; // Delta-v + private ReagentSortMethod _currentSortMethod = ReagentSortMethod.Alphabetical; // Delta-v + private ChemMasterBoundUserInterfaceState? _lastState; // Delta-v + private int _transferAmount = 50; // Delta-v private const string PillsRsiPath = "/Textures/Objects/Specific/Chemistry/pills.rsi"; @@ -46,9 +46,9 @@ public ChemMasterWindow() RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - AmountLabel.HorizontalAlignment = HAlignment.Center; - AmountLineEdit.OnTextEntered += (args) => SetAmountText(args.Text); - AmountLineEdit.OnFocusExit += (args) => SetAmountText(args.Text); + AmountLabel.HorizontalAlignment = HAlignment.Center; // Delta-v + AmountLineEdit.OnTextEntered += (args) => SetAmountText(args.Text); // Delta-v + AmountLineEdit.OnFocusExit += (args) => SetAmountText(args.Text); // Delta-v // Pill type selection buttons, in total there are 20 pills. // Pill rsi file should have states named as pill1, pill2, and so on. @@ -100,6 +100,7 @@ public ChemMasterWindow() Tabs.SetTabTitle(0, Loc.GetString("chem-master-window-input-tab")); Tabs.SetTabTitle(1, Loc.GetString("chem-master-window-output-tab")); + // Delta-v Start - Necessary for sorting/custom amounts SortMethod.AddItem( Loc.GetString("chem-master-window-sort-method-Alphabetical-text"), (int) ReagentSortMethod.Alphabetical); @@ -127,12 +128,13 @@ public ChemMasterWindow() PillSortMethod.OnItemSelected += HandleChildPressed; - var amounts = new List() - { - 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 125, 150, 175, 200, 225, 250, 275, 300, 500 - }; + // Delta-v - Specific amounts to allow for better, specific items + int[] amounts = + [ + 1, 5, 10, 15, 20, 25, 30, 33, 40, 45, 50, 55, 60, 66, 70, 75, 80, 85, 90, 99, 100, 125, 150, 175, 200, 225, 250, 275, 300, 500 + ]; - for (int i = 0; i < amounts.Count; i++) + for (int i = 0; i < amounts.Length; i++) { var styleClass = StyleBase.ButtonOpenBoth; var amount = amounts[i]; @@ -203,24 +205,26 @@ private void SetAmountText(string newText) AmountLabel.Text = localizedAmount; AmountLineEdit.SetText(string.Empty); OnTransferAmountChanged?.Invoke(amount); + // Delta-v end } - private ReagentButton MakeReagentButton(string text, ReagentId id, bool isBuffer) + private ReagentButton MakeReagentButton(string text, ReagentId id, bool isBuffer) // Delta-v { - var reagentTransferButton = new ReagentButton(text, id, isBuffer); + var reagentTransferButton = new ReagentButton(text, id, isBuffer); // Delta-v reagentTransferButton.OnPressed += args - => OnReagentButtonPressed?.Invoke(args, reagentTransferButton, _transferAmount, Tabs.CurrentTab == 1); + => OnReagentButtonPressed?.Invoke(args, reagentTransferButton, _transferAmount, Tabs.CurrentTab == 1); // Delta-v 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 ReagentButton? CreateReagentTransferButton(ReagentId reagent, bool isBuffer, bool addReagentButtons) + private ReagentButton? CreateReagentTransferButton(ReagentId reagent, bool isBuffer, bool addReagentButtons) // Delta-v { if (!addReagentButtons) return null; // Return an empty list if reagentTransferButton creation is disabled. + // Delta-v var reagentTransferButton = MakeReagentButton( Loc.GetString("chem-master-window-transfer-button"), reagent, @@ -245,19 +249,19 @@ public void UpdateState(BoundUserInterfaceState state) // Ensure the Panel Info is updated, including UI elements for Buffer Volume, Output Container and so on UpdatePanelInfo(castState); - HandleSortMethodChange(castState.SortMethod); + HandleSortMethodChange(castState.SortMethod); // Delta-v - _transferAmount = castState.TransferringAmount; - BufferCurrentVolume.Text = $" {castState.PillBufferCurrentVolume?.Int() ?? 0}u"; + _transferAmount = castState.TransferringAmount; // Delta-v + BufferCurrentVolume.Text = $" {castState.PillBufferCurrentVolume?.Int() ?? 0}u"; // Delta-v - InputEjectButton.Disabled = castState.ContainerInfo is null; - CreateBottleButton.Disabled = castState.PillBufferReagents.Count == 0; - CreatePillButton.Disabled = castState.PillBufferReagents.Count == 0; + InputEjectButton.Disabled = castState.ContainerInfo is null; // Delta-v + CreateBottleButton.Disabled = castState.PillBufferReagents.Count == 0; // Delta-v + CreatePillButton.Disabled = castState.PillBufferReagents.Count == 0; // Delta-v UpdateDosageFields(castState); } - private FixedPoint2 CurrentStateBufferVolume(ChemMasterBoundUserInterfaceState state) + private FixedPoint2 CurrentStateBufferVolume(ChemMasterBoundUserInterfaceState state) // Delta-v { return (Tabs.CurrentTab == 0 ? state.BufferCurrentVolume : state.PillBufferCurrentVolume) ?? 0; } @@ -265,21 +269,25 @@ private FixedPoint2 CurrentStateBufferVolume(ChemMasterBoundUserInterfaceState s //assign default values for pill and bottle fields. private void UpdateDosageFields(ChemMasterBoundUserInterfaceState castState) { - var bufferVolume = castState.PillBufferCurrentVolume?.Int() ?? 0; - PillDosage.Value = (int) Math.Min(bufferVolume, castState.PillDosageLimit); + var bufferVolume = castState.PillBufferCurrentVolume?.Int() ?? 0; // Delta-v + PillDosage.Value = (int) Math.Min(bufferVolume, castState.PillDosageLimit); // Delta-v PillTypeButtons[castState.SelectedPillType].Pressed = true; - PillNumber.IsValid = x => x >= 0; + PillNumber.IsValid = x => x >= 0; // Delta-v PillDosage.IsValid = x => x > 0 && x <= castState.PillDosageLimit; - BottleDosage.IsValid = x => x >= 0; + BottleDosage.IsValid = x => x >= 0; // Delta-v // Avoid division by zero if (PillDosage.Value > 0) - PillNumber.Value = bufferVolume / PillDosage.Value; + { + PillNumber.Value = bufferVolume / PillDosage.Value; // Delta-v + } else + { PillNumber.Value = 0; + } - BottleDosage.Value = bufferVolume; + BottleDosage.Value = bufferVolume; // Delta-v } /// /// Generate a product label based on reagents in the buffer. @@ -287,11 +295,11 @@ private void UpdateDosageFields(ChemMasterBoundUserInterfaceState castState) /// State data sent by the server. private string GenerateLabel(ChemMasterBoundUserInterfaceState state) { - if (CurrentStateBufferVolume(state) == 0) + if (CurrentStateBufferVolume(state) == 0) // Delta-v return ""; - var buffer = Tabs.CurrentTab == 0 ? state.BufferReagents : state.PillBufferReagents; - var reagent = buffer.OrderBy(r => r.Quantity).First().Reagent; + var buffer = Tabs.CurrentTab == 0 ? state.BufferReagents : state.PillBufferReagents; // Delta-v + var reagent = buffer.OrderBy(r => r.Quantity).First().Reagent; // Delta-v _prototypeManager.TryIndex(reagent.Prototype, out ReagentPrototype? proto); return proto?.LocalizedName ?? ""; @@ -303,9 +311,9 @@ private string GenerateLabel(ChemMasterBoundUserInterfaceState state) /// State data for the dispenser. private void UpdatePanelInfo(ChemMasterBoundUserInterfaceState state) { - BuildContainerUI(ContainerInfoContainer, state.ContainerInfo, true); - BuildBufferInfo(state); - BuildPillBufferInfo(state); + BuildContainerUI(ContainerInfoContainer, state.ContainerInfo, true); // Delta-v + BuildBufferInfo(state); // Delta-v + BuildPillBufferInfo(state); // Delta-v } private void BuildBufferInfo(ChemMasterBoundUserInterfaceState state) @@ -333,14 +341,16 @@ private void BuildBufferInfo(ChemMasterBoundUserInterfaceState state) }; bufferHBox.AddChild(bufferVol); - var bufferReagents = state.BufferReagents.OrderBy(x => x.Reagent.Prototype); + var bufferReagents = state.BufferReagents.OrderBy(x => x.Reagent.Prototype); // Delta-v - if (_currentSortMethod == ReagentSortMethod.Amount) - bufferReagents = bufferReagents.OrderByDescending(x => x.Quantity); + if (_currentSortMethod == ReagentSortMethod.Amount) // Delta-v + bufferReagents = bufferReagents.OrderByDescending(x => x.Quantity); // Delta-v - HandleBuffer(_currentSortMethod == ReagentSortMethod.Time ? state.BufferReagents : bufferReagents, false); + HandleBuffer(_currentSortMethod == ReagentSortMethod.Time ? state.BufferReagents : bufferReagents, false); // Delta-v } + // Delta-v Start + private void BuildPillBufferInfo(ChemMasterBoundUserInterfaceState state) { PillBufferInfo.Children.Clear(); @@ -374,7 +384,7 @@ private void BuildPillBufferInfo(ChemMasterBoundUserInterfaceState state) HandleBuffer(_currentSortMethod == ReagentSortMethod.Time ? state.PillBufferReagents : bufferReagents, true); } - private void HandleBuffer(IEnumerable reagents, bool pillBuffer) + private void HandleBuffer(IEnumerable reagents, bool pillBuffer) // Delta-v { var rowCount = 0; var pillRowCount = 0; @@ -399,6 +409,8 @@ private void HandleBuffer(IEnumerable reagents, bool pillBuffer } } + // Delta-v End + private void BuildContainerUI(Control control, ContainerInfo? info, bool addReagentButtons) { control.Children.Clear(); @@ -497,8 +509,10 @@ private Control BuildReagentRow(Color reagentColor, int rowCount, string name, R } }; - if (reagentButtonConstructor != null) + if (reagentButtonConstructor != null) // Delta-v - add + { rowContainer.AddChild(reagentButtonConstructor); + } //Apply panencontainer to allow for striped rows return new PanelContainer @@ -519,7 +533,7 @@ public sealed class ReagentButton : Button { public bool IsBuffer = true; public ReagentId Id { get; set; } - public ReagentButton(string text, ReagentId id, bool isBuffer) + public ReagentButton(string text, ReagentId id, bool isBuffer) // Delta-v { AddStyleClass(StyleBase.ButtonOpenLeft); Text = text; @@ -528,6 +542,7 @@ public ReagentButton(string text, ReagentId id, bool isBuffer) } } + // Delta-v public enum ReagentSortMethod { Time, From 6ee793a3b7add5da51ff9dcfade48cf90bef91b4 Mon Sep 17 00:00:00 2001 From: sleepyyapril Date: Mon, 27 Jan 2025 02:54:24 -0400 Subject: [PATCH 08/20] Remove unnecessary addition --- Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs index 9e3103133e2..5c15153e559 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs @@ -279,13 +279,9 @@ private void UpdateDosageFields(ChemMasterBoundUserInterfaceState castState) // Avoid division by zero if (PillDosage.Value > 0) - { PillNumber.Value = bufferVolume / PillDosage.Value; // Delta-v - } else - { PillNumber.Value = 0; - } BottleDosage.Value = bufferVolume; // Delta-v } @@ -509,10 +505,8 @@ private Control BuildReagentRow(Color reagentColor, int rowCount, string name, R } }; - if (reagentButtonConstructor != null) // Delta-v - add - { + if (reagentButtonConstructor != null) // Delta-v - add button for reagent transfer rowContainer.AddChild(reagentButtonConstructor); - } //Apply panencontainer to allow for striped rows return new PanelContainer From edf01664e8efd3f3c6f3fbf26af809f2f84b9baa Mon Sep 17 00:00:00 2001 From: sleepyyapril Date: Sat, 1 Feb 2025 03:16:58 -0400 Subject: [PATCH 09/20] review stuff --- .../UI/ChemMasterBoundUserInterface.cs | 6 +- .../Chemistry/UI/ChemMasterWindow.xaml | 4 ++ .../Components/ChemMasterComponent.cs | 7 ++ .../EntitySystems/ChemMasterSystem.cs | 65 ++++++++----------- Content.Shared/Chemistry/SharedChemMaster.cs | 16 ++--- 5 files changed, 48 insertions(+), 50 deletions(-) diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs index 08e3125523f..e5cb06b14d0 100644 --- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs @@ -10,11 +10,15 @@ namespace Content.Client.Chemistry.UI /// Initializes a and updates it when new server messages are received. /// [UsedImplicitly] - public sealed class ChemMasterBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) // Delta-v + public sealed class ChemMasterBoundUserInterface : BoundUserInterface { [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. diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml index 96c57ef08f2..3cc8bf97b78 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml @@ -4,6 +4,7 @@ xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client" MinSize="800 00" Title="{Loc 'chem-master-bound-user-interface-title'}"> + @@ -14,6 +15,7 @@ + @@ -29,6 +31,7 @@ + @@ -107,6 +110,7 @@ + diff --git a/Content.Server/Chemistry/Components/ChemMasterComponent.cs b/Content.Server/Chemistry/Components/ChemMasterComponent.cs index a3abc3b98e7..3bd8bffb8b8 100644 --- a/Content.Server/Chemistry/Components/ChemMasterComponent.cs +++ b/Content.Server/Chemistry/Components/ChemMasterComponent.cs @@ -21,9 +21,16 @@ public sealed partial class ChemMasterComponent : Component [DataField("clickSound"), ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"); + /// + /// DeltaV: The enum integer value for which SortMethod the user has selected. + /// Directly castable as a SortMethod, but nothing server-side needs that. + /// [DataField] public int SortMethod; + /// + /// DeltaV: How much is the user transferring on each transfer? + /// [DataField] public int TransferringAmount; } diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index f05a8125126..a366984c5ac 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -38,13 +38,11 @@ public sealed class ChemMasterSystem : EntitySystem [Dependency] private readonly StorageSystem _storageSystem = default!; [Dependency] private readonly LabelSystem _labelSystem = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; [ValidatePrototypeId] private const string PillPrototypeId = "Pill"; - [ValidatePrototypeId] - private const string PillCanisterPrototypeId = "PillCanister"; + private EntProtoId _pillCanisterPrototypeId = "PillCanister"; public override void Initialize() { @@ -60,12 +58,14 @@ public override void Initialize() SubscribeLocalEvent(OnReagentButtonMessage); SubscribeLocalEvent(OnCreatePillsMessage); SubscribeLocalEvent(OnOutputToBottleMessage); - SubscribeLocalEvent(OnSortMethodUpdated); - SubscribeLocalEvent(OnTransferringAmountUpdated); + SubscribeLocalEvent(OnSortMethodUpdated); // Delta-v + SubscribeLocalEvent(OnTransferringAmountUpdated); // Delta-v } - 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) { @@ -76,7 +76,7 @@ private void UpdateUiState(Entity ent, bool updateLabel = f if (!_solutionContainerSystem.TryGetSolution(owner, SharedChemMaster.PillBufferSolutionName, out _, out var pillBufferSolution)) return; - var container = _itemSlotsSystem.GetItemOrNull(owner, SharedChemMaster.InputSlotName); + var inputContainer = _itemSlotsSystem.GetItemOrNull(owner, SharedChemMaster.InputSlotName); var bufferReagents = bufferSolution.Contents; var bufferCurrentVolume = bufferSolution.Volume; @@ -85,16 +85,9 @@ private void UpdateUiState(Entity ent, bool updateLabel = f var pillBufferCurrentVolume = pillBufferSolution.Volume; var state = new ChemMasterBoundUserInterfaceState( - BuildInputContainerInfo(container), - bufferReagents, - pillBufferReagents, - bufferCurrentVolume, - pillBufferCurrentVolume, - chemMaster.PillType, - chemMaster.PillDosageLimit, - updateLabel, - ent.Comp.SortMethod, - ent.Comp.TransferringAmount); + BuildInputContainerInfo(inputContainer), + bufferReagents, pillBufferReagents, bufferCurrentVolume, pillBufferCurrentVolume, // Delta-v: implement pill buffer + chemMaster.PillType, chemMaster.PillDosageLimit, updateLabel, ent.Comp.SortMethod, ent.Comp.TransferringAmount); // Delta-v: send comp values to client _userInterfaceSystem.SetUiState(owner, ChemMasterUiKey.Key, state); } @@ -112,34 +105,33 @@ private void OnSetPillTypeMessage(Entity chemMaster, ref Ch private void OnReagentButtonMessage(Entity chemMaster, ref ChemMasterReagentAmountButtonMessage message) { - TransferReagents(chemMaster, message.ReagentId, chemMaster.Comp.TransferringAmount, message.FromBuffer, message.IsOutput); + TransferReagents(chemMaster, message.ReagentId, chemMaster.Comp.TransferringAmount, message.FromBuffer, message.IsOutput); // Delta-v ClickSound(chemMaster); } - private void TransferReagents(Entity chemMaster, ReagentId id, FixedPoint2 amount, bool fromBuffer, bool isOutput) + private void TransferReagents(Entity chemMaster, ReagentId id, FixedPoint2 amount, bool fromBuffer, bool isOutput) // Delta-v { var container = _itemSlotsSystem.GetItemOrNull(chemMaster, SharedChemMaster.InputSlotName); if (container is null || !_solutionContainerSystem.TryGetFitsInDispenser(container.Value, out var containerSoln, out var containerSolution) || !_solutionContainerSystem.TryGetSolution(chemMaster.Owner, SharedChemMaster.BufferSolutionName, out _, out var bufferSolution) || - !_solutionContainerSystem.TryGetSolution(chemMaster.Owner, SharedChemMaster.PillBufferSolutionName, out _, out var pillBufferSolution)) + !_solutionContainerSystem.TryGetSolution(chemMaster.Owner, SharedChemMaster.PillBufferSolutionName, out _, out var pillBufferSolution)) // Delta-v return; + var solution = isOutput ? pillBufferSolution : bufferSolution; // Delta-v + if (fromBuffer) // Buffer to container { amount = FixedPoint2.Min(amount, containerSolution.AvailableVolume); - var solution = isOutput ? pillBufferSolution : bufferSolution; - amount = solution.RemoveReagent(id, amount, preserveOrder: true); + amount = solution.RemoveReagent(id, amount, preserveOrder: true); // Delta-v _solutionContainerSystem.TryAddReagent(containerSoln.Value, id, amount, out _); } else // Container to buffer { amount = FixedPoint2.Min(amount, containerSolution.GetReagentQuantity(id)); _solutionContainerSystem.RemoveReagent(containerSoln.Value, id, amount); - - var solution = isOutput ? pillBufferSolution : bufferSolution; - solution.AddReagent(id, amount); + solution.AddReagent(id, amount); // Delta-v } UpdateUiState(chemMaster, updateLabel: true); @@ -150,12 +142,14 @@ private void OnCreatePillsMessage(Entity chemMaster, ref Ch var user = message.Actor; var maybeContainer = _itemSlotsSystem.GetItemOrNull(chemMaster, SharedChemMaster.OutputSlotName); + // Delta-v start if (maybeContainer == null) { - var canister = _entityManager.SpawnEntity(PillCanisterPrototypeId, Transform(chemMaster.Owner).Coordinates); + var canister = Spawn(_pillCanisterPrototypeId, Transform(chemMaster.Owner).Coordinates); _itemSlotsSystem.TryInsert(chemMaster.Owner, SharedChemMaster.OutputSlotName, canister, null); maybeContainer = canister; } + // Delta-v end if (maybeContainer is not { Valid: true } container || !TryComp(container, out StorageComponent? storage)) @@ -187,14 +181,9 @@ private void OnCreatePillsMessage(Entity chemMaster, ref Ch _storageSystem.Insert(container, item, out _, user: user, storage); _labelSystem.Label(item, message.Label); - var hasItemSolution = _solutionContainerSystem.EnsureSolutionEntity( - (item, null), - SharedChemMaster.PillSolutionName, - out var itemSolution, - message.Dosage); - - if (!hasItemSolution || itemSolution is null) - continue; + _solutionContainerSystem.EnsureSolutionEntity(item, SharedChemMaster.PillSolutionName,out var itemSolution ,message.Dosage); + if (!itemSolution.HasValue) + return; _solutionContainerSystem.TryAddSolution(itemSolution.Value, withdrawal.SplitSolution(message.Dosage)); @@ -203,9 +192,7 @@ private void OnCreatePillsMessage(Entity chemMaster, ref Ch Dirty(item, pill); // Log pill creation by a user - _adminLogger.Add( - LogType.Action, - LogImpact.Low, + _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user):user} printed {ToPrettyString(item):pill} {SharedSolutionContainerSystem.ToPrettyString(itemSolution.Value.Comp.Solution)}"); } @@ -218,12 +205,14 @@ private void OnOutputToBottleMessage(Entity chemMaster, ref var user = message.Actor; var maybeContainer = _itemSlotsSystem.GetItemOrNull(chemMaster, SharedChemMaster.OutputSlotName); + // Delta-v start if (maybeContainer == null) { - var canister = _entityManager.SpawnEntity(PillCanisterPrototypeId, Transform(chemMaster.Owner).Coordinates); + var canister = Spawn(_pillCanisterPrototypeId, Transform(chemMaster.Owner).Coordinates); _itemSlotsSystem.TryInsert(chemMaster.Owner, SharedChemMaster.OutputSlotName, canister, null); maybeContainer = canister; } + // Delta-v end if (maybeContainer is not { Valid: true } container || !_solutionContainerSystem.TryGetSolution(container, SharedChemMaster.BottleSolutionName, out var soln, out var solution)) diff --git a/Content.Shared/Chemistry/SharedChemMaster.cs b/Content.Shared/Chemistry/SharedChemMaster.cs index c3dfe2b5f0f..06895330f01 100644 --- a/Content.Shared/Chemistry/SharedChemMaster.cs +++ b/Content.Shared/Chemistry/SharedChemMaster.cs @@ -11,7 +11,7 @@ public sealed class SharedChemMaster { public const uint PillTypes = 20; public const string BufferSolutionName = "buffer"; - public const string PillBufferSolutionName = "pillBuffer"; + public const string PillBufferSolutionName = "pillBuffer"; // Delta-v public const string InputSlotName = "beakerSlot"; public const string OutputSlotName = "outputSlot"; public const string PillSolutionName = "food"; @@ -34,16 +34,16 @@ public ChemMasterSetPillTypeMessage(uint pillType) public sealed class ChemMasterReagentAmountButtonMessage : BoundUserInterfaceMessage { public readonly ReagentId ReagentId; - public readonly int Amount; + public readonly int Amount; // Delta-v public readonly bool FromBuffer; - public readonly bool IsOutput; + public readonly bool IsOutput; // Delta-v - public ChemMasterReagentAmountButtonMessage(ReagentId reagentId, int amount, bool fromBuffer, bool isOutput) + public ChemMasterReagentAmountButtonMessage(ReagentId reagentId, int amount, bool fromBuffer, bool isOutput) // Delta-v { ReagentId = reagentId; Amount = amount; FromBuffer = fromBuffer; - IsOutput = isOutput; + IsOutput = isOutput; // Delta-v } } @@ -87,12 +87,6 @@ public sealed class ChemMasterTransferringAmountUpdated(int transferringAmount) public readonly int TransferringAmount = transferringAmount; } - public enum ChemMasterMode - { - Transfer, - Discard, - } - /// /// Information about the capacity and contents of a container for display in the UI /// From 403c01e63ede426b3af4efaa87576346c4d6583f Mon Sep 17 00:00:00 2001 From: sleepyyapril Date: Sat, 1 Feb 2025 03:22:32 -0400 Subject: [PATCH 10/20] Better comments? --- .../Chemistry/UI/ChemMasterWindow.xaml | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml index 3cc8bf97b78..83d1bf9549c 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml @@ -2,9 +2,9 @@ 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="800 00" + MinSize="800 800" Title="{Loc 'chem-master-bound-user-interface-title'}"> - + @@ -15,7 +15,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -107,25 +107,26 @@ public readonly IReadOnlyList BufferReagents; - + public readonly FixedPoint2? BufferCurrentVolume; public readonly uint SelectedPillType; From f9dc67bedcdb1c83d7ec62c00220bba06df508c5 Mon Sep 17 00:00:00 2001 From: sleepyyapril Date: Sun, 2 Feb 2025 01:48:09 -0400 Subject: [PATCH 20/20] comment more! --- Content.Shared/Chemistry/SharedChemMaster.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Content.Shared/Chemistry/SharedChemMaster.cs b/Content.Shared/Chemistry/SharedChemMaster.cs index f1dd13667e7..1cfe551347c 100644 --- a/Content.Shared/Chemistry/SharedChemMaster.cs +++ b/Content.Shared/Chemistry/SharedChemMaster.cs @@ -150,7 +150,7 @@ public sealed class ChemMasterBoundUserInterfaceState : BoundUserInterfaceState public readonly FixedPoint2? PillBufferCurrentVolume; // DeltaV - public ChemMasterBoundUserInterfaceState( + public ChemMasterBoundUserInterfaceState( // DeltaV ContainerInfo? inputContainerInfo, IReadOnlyList bufferReagents, IReadOnlyList pillBufferReagents, @@ -169,11 +169,11 @@ public ChemMasterBoundUserInterfaceState( PillDosageLimit = pillDosageLimit; UpdateLabel = updateLabel; - SortMethod = sortMethod; - TransferringAmount = transferringAmount; + SortMethod = sortMethod; // DeltaV + TransferringAmount = transferringAmount; // DeltaV - PillBufferReagents = pillBufferReagents; - PillBufferCurrentVolume = pillBufferCurrentVolume; + PillBufferReagents = pillBufferReagents; // DeltaV + PillBufferCurrentVolume = pillBufferCurrentVolume; // DeltaV } }