Fix & extend add reagent verb (#4954)
* AddReagentWindow * addReagent command * functional UI * fix networking * add comments & docstrings * Remove unecesary system * cleanup & close-eui * tweak default window size * fix EUI closing error * fix merge issues * fix merge
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
<SS14Window
|
||||
SetSize="250 300"
|
||||
Margin="4 0"
|
||||
xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Name="QuantityBox" Orientation="Horizontal" Margin ="0 4">
|
||||
<Label Text="{Loc 'admin-add-reagent-window-amount-label'}" Margin="0 0 10 0"/>
|
||||
</BoxContainer>
|
||||
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'admin-add-reagent-window-search-placeholder'}" HorizontalExpand="True" Margin ="0 4"/>
|
||||
<ItemList Name="ReagentList" SelectMode="Single" VerticalExpand="True" Margin ="0 4"/>
|
||||
<Button Name="AddButton" HorizontalExpand="True" Margin ="0 4" />
|
||||
</BoxContainer>
|
||||
</SS14Window>
|
||||
@@ -0,0 +1,135 @@
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Administration.UI.ManageSolutions
|
||||
{
|
||||
/// <summary>
|
||||
/// A debug window that allows you to add a reagent to a solution. Intended to be used with <see
|
||||
/// cref="EditSolutionsWindow"/>
|
||||
/// </summary>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AddReagentWindow : SS14Window
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
|
||||
|
||||
private readonly EntityUid _targetEntity;
|
||||
private string _targetSolution;
|
||||
private ReagentPrototype? _selectedReagent;
|
||||
|
||||
// FloatSpinBox does not (yet?) play nice with xaml
|
||||
private FloatSpinBox _quantitySpin = new(1, 2) { Value = 10, HorizontalExpand = true};
|
||||
|
||||
public AddReagentWindow(EntityUid targetEntity, string targetSolution)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
Title = Loc.GetString("admin-add-reagent-window-title", ("solution", targetSolution));
|
||||
|
||||
_targetEntity = targetEntity;
|
||||
_targetSolution = targetSolution;
|
||||
|
||||
QuantityBox.AddChild(_quantitySpin);
|
||||
|
||||
ReagentList.OnItemSelected += ReagentListSelected;
|
||||
ReagentList.OnItemDeselected += ReagentListDeselected;
|
||||
SearchBar.OnTextChanged += (_) => UpdateReagentPrototypes(SearchBar.Text);
|
||||
_quantitySpin.OnValueChanged += (_) => UpdateAddButton();
|
||||
AddButton.OnPressed += AddReagent;
|
||||
|
||||
UpdateReagentPrototypes();
|
||||
UpdateAddButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute a console command that asks the server to add the selected reagent.
|
||||
/// </summary>
|
||||
private void AddReagent(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (_selectedReagent == null)
|
||||
return;
|
||||
|
||||
var quantity = _quantitySpin.Value.ToString("F2");
|
||||
var command = $"addreagent {_targetEntity} {_targetSolution} {_selectedReagent.ID} {quantity}";
|
||||
_consoleHost.ExecuteCommand(command);
|
||||
}
|
||||
|
||||
private void ReagentListSelected(ItemList.ItemListSelectedEventArgs obj)
|
||||
{
|
||||
_selectedReagent = (ReagentPrototype) obj.ItemList[obj.ItemIndex].Metadata!;
|
||||
UpdateAddButton();
|
||||
}
|
||||
|
||||
private void ReagentListDeselected(ItemList.ItemListDeselectedEventArgs obj)
|
||||
{
|
||||
_selectedReagent = null;
|
||||
UpdateAddButton();
|
||||
}
|
||||
|
||||
public void UpdateSolution(string? selectedSolution)
|
||||
{
|
||||
if (selectedSolution == null)
|
||||
{
|
||||
Close();
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
_targetSolution = selectedSolution;
|
||||
Title = Loc.GetString("admin-add-reagent-window-title", ("solution", _targetSolution));
|
||||
UpdateAddButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the Text and enabled/disabled status of the button that actually adds the reagent.
|
||||
/// </summary>
|
||||
private void UpdateAddButton()
|
||||
{
|
||||
AddButton.Disabled = true;
|
||||
if (_selectedReagent == null)
|
||||
{
|
||||
AddButton.Text = Loc.GetString("admin-add-reagent-window-add-invalid-reagent");
|
||||
return;
|
||||
}
|
||||
|
||||
AddButton.Text = Loc.GetString("admin-add-reagent-window-add",
|
||||
("quantity", _quantitySpin.Value.ToString("F2")),
|
||||
("reagent", _selectedReagent.ID));
|
||||
|
||||
AddButton.Disabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all reagent prototypes and show them in an item list.
|
||||
/// </summary>
|
||||
private void UpdateReagentPrototypes(string? filter = null)
|
||||
{
|
||||
ReagentList.Clear();
|
||||
foreach (var reagent in _prototypeManager.EnumeratePrototypes<ReagentPrototype>())
|
||||
{
|
||||
if (!string.IsNullOrEmpty(filter) &&
|
||||
!reagent.ID.ToLowerInvariant().Contains(filter.Trim().ToLowerInvariant()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemList.Item regentItem = new(ReagentList)
|
||||
{
|
||||
Metadata = reagent,
|
||||
Text = reagent.ID
|
||||
};
|
||||
|
||||
ReagentList.Add(regentItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Content.Client.Eui;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Eui;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Client.Administration.UI.ManageSolutions
|
||||
{
|
||||
/// <summary>
|
||||
/// Admin Eui for displaying and editing the reagents in a solution.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed class EditSolutionsEui : BaseEui
|
||||
{
|
||||
private readonly EditSolutionsWindow _window;
|
||||
|
||||
public EditSolutionsEui()
|
||||
{
|
||||
_window = new EditSolutionsWindow();
|
||||
_window.OnClose += () => SendMessage(new EditSolutionsEuiMsg.Close());
|
||||
}
|
||||
|
||||
public override void Opened()
|
||||
{
|
||||
base.Opened();
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
public override void Closed()
|
||||
{
|
||||
base.Closed();
|
||||
_window.OnClose -= () => SendMessage(new EditSolutionsEuiMsg.Close());
|
||||
_window.Close();
|
||||
}
|
||||
|
||||
public override void HandleState(EuiStateBase baseState)
|
||||
{
|
||||
var state = (EditSolutionsEuiState) baseState;
|
||||
_window.SetTargetEntity(state.Target);
|
||||
_window.UpdateSolutions(state.Solutions);
|
||||
_window.UpdateReagents();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<SS14Window
|
||||
SetSize="300 300"
|
||||
Margin="4 0"
|
||||
xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 4">
|
||||
<Label Text ="{Loc 'admin-solutions-window-solution-label'}" Margin="0 0 10 0"/>
|
||||
<OptionButton Name="SolutionOption" HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
<Label Name="TotalLabel" HorizontalExpand="True" Margin="0 4"/>
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" Margin="0 4">
|
||||
<BoxContainer Name="ReagentList" Orientation="Vertical"/>
|
||||
</ScrollContainer>
|
||||
<Button Name="AddButton" Text="{Loc 'admin-solutions-window-add-new-button'}" HorizontalExpand="True" Margin="0 4"/>
|
||||
</BoxContainer>
|
||||
</SS14Window>
|
||||
@@ -0,0 +1,179 @@
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Client.Administration.UI.ManageSolutions
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple window that displays solutions and their contained reagents. Allows you to edit the reagent quantities and add new reagents.
|
||||
/// </summary>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class EditSolutionsWindow : SS14Window
|
||||
{
|
||||
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
private EntityUid _target = EntityUid.Invalid;
|
||||
private string? _selectedSolution;
|
||||
private AddReagentWindow? _addReagentWindow;
|
||||
private Dictionary<string, Solution>? _solutions;
|
||||
|
||||
public EditSolutionsWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
SolutionOption.OnItemSelected += SolutionSelected;
|
||||
AddButton.OnPressed += OpenAddReagentWindow;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
_addReagentWindow?.Close();
|
||||
_addReagentWindow?.Dispose();
|
||||
}
|
||||
|
||||
public void SetTargetEntity(EntityUid target)
|
||||
{
|
||||
_target = target;
|
||||
|
||||
var targetName = _entityManager.TryGetEntity(target, out var entity)
|
||||
? entity.Name
|
||||
: string.Empty;
|
||||
|
||||
Title = Loc.GetString("admin-solutions-window-title", ("targetName", targetName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the capacity label and re-create the reagent list
|
||||
/// </summary>
|
||||
public void UpdateReagents()
|
||||
{
|
||||
ReagentList.DisposeAllChildren();
|
||||
|
||||
if (_selectedSolution == null || _solutions == null)
|
||||
return;
|
||||
|
||||
if (!_solutions.TryGetValue(_selectedSolution, out var solution))
|
||||
return;
|
||||
|
||||
TotalLabel.Text = Loc.GetString("admin-solutions-window-capacity-label",
|
||||
("currentVolume", solution.TotalVolume),
|
||||
("maxVolume",solution.MaxVolume));
|
||||
|
||||
foreach (var reagent in solution)
|
||||
{
|
||||
AddReagentEntry(reagent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a single reagent entry to the list
|
||||
/// </summary>
|
||||
private void AddReagentEntry(Solution.ReagentQuantity reagent)
|
||||
{
|
||||
var box = new BoxContainer();
|
||||
var spin = new FloatSpinBox(1, 2);
|
||||
|
||||
spin.Value = reagent.Quantity.Float();
|
||||
spin.OnValueChanged += (args) => SetReagent(args, reagent.ReagentId);
|
||||
spin.HorizontalExpand = true;
|
||||
|
||||
box.AddChild(new Label() { Text = reagent.ReagentId , HorizontalExpand = true});
|
||||
box.AddChild(spin);
|
||||
|
||||
ReagentList.AddChild(box);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute a command to modify the reagents in the solution.
|
||||
/// </summary>
|
||||
private void SetReagent(FloatSpinBox.FloatSpinBoxEventArgs args, string reagentId)
|
||||
{
|
||||
if (_solutions == null || _selectedSolution == null)
|
||||
return;
|
||||
|
||||
var current = _solutions[_selectedSolution].GetReagentQuantity(reagentId);
|
||||
var delta = args.Value - current.Float();
|
||||
|
||||
if (MathF.Abs(delta) < 0.01)
|
||||
return;
|
||||
|
||||
var command = $"addreagent {_target} {_selectedSolution} {reagentId} {delta}";
|
||||
_consoleHost.ExecuteCommand(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a new window that has options to add new reagents to the solution.
|
||||
/// </summary>
|
||||
private void OpenAddReagentWindow(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_selectedSolution))
|
||||
return;
|
||||
|
||||
_addReagentWindow?.Close();
|
||||
_addReagentWindow?.Dispose();
|
||||
|
||||
_addReagentWindow = new AddReagentWindow(_target, _selectedSolution);
|
||||
_addReagentWindow.OpenCentered();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When a new solution is selected, set _selectedSolution and update the reagent list.
|
||||
/// </summary>
|
||||
private void SolutionSelected(OptionButton.ItemSelectedEventArgs args)
|
||||
{
|
||||
SolutionOption.SelectId(args.Id);
|
||||
_selectedSolution = (string?) SolutionOption.SelectedMetadata;
|
||||
_addReagentWindow?.UpdateSolution(_selectedSolution);
|
||||
UpdateReagents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the solution options.
|
||||
/// </summary>
|
||||
public void UpdateSolutions(Dictionary<string, Solution>? solutions)
|
||||
{
|
||||
SolutionOption.Clear();
|
||||
_solutions = solutions;
|
||||
|
||||
if (_solutions == null)
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
foreach (var solution in _solutions.Keys)
|
||||
{
|
||||
SolutionOption.AddItem(solution, i);
|
||||
SolutionOption.SetItemMetadata(i, solution);
|
||||
|
||||
if (solution == _selectedSolution)
|
||||
SolutionOption.Select(i);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (SolutionOption.ItemCount == 0)
|
||||
{
|
||||
// No applicable solutions
|
||||
Close();
|
||||
Dispose();
|
||||
}
|
||||
|
||||
if (_selectedSolution == null || !_solutions.ContainsKey(_selectedSolution))
|
||||
{
|
||||
// the previously selected solution is no longer valid.
|
||||
SolutionOption.Select(0);
|
||||
_selectedSolution = (string?) SolutionOption.SelectedMetadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user