mirror of
https://github.com/wega-team/ss14-wega.git
synced 2026-06-09 10:06:49 +02:00
284 lines
10 KiB
C#
284 lines
10 KiB
C#
using System.Linq;
|
|
using System.Numerics;
|
|
using Content.Client.UserInterface.Controls;
|
|
using Content.Shared.Chemistry.Reagent;
|
|
using Content.Shared.FixedPoint;
|
|
using Content.Shared.Injector.Fabticator;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Client._Wega.Medical.Ui;
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class InjectorFabticatorWindow : FancyWindow
|
|
{
|
|
[Dependency] private IPrototypeManager _prototypeManager = default!;
|
|
[Dependency] private IEntityManager _entityManager = default!;
|
|
|
|
public event Action? EjectButtonPressed;
|
|
public event Action<int, string?>? ProduceButtonPressed;
|
|
public event Action<ReagentId, FixedPoint2>? ReagentAdded;
|
|
public event Action<ReagentId>? ReagentRemoved;
|
|
public event Action<ReagentId, FixedPoint2>? TransferToBufferPressed;
|
|
public event Action<ReagentId, FixedPoint2>? TransferToBeakerPressed;
|
|
|
|
private Dictionary<ReagentId, ReagentPrototype> _beakerReagents = new();
|
|
private Dictionary<ReagentId, ReagentPrototype> _bufferReagents = new();
|
|
|
|
public InjectorFabticatorWindow()
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
IoCManager.InjectDependencies(this);
|
|
|
|
// Setup button events
|
|
TransferToBufferButton.OnPressed += OnTransferToBufferPressed;
|
|
TransferToBeakerButton.OnPressed += OnTransferToBeakerPressed;
|
|
BeakerTransferAmount.OnValueChanged += OnSpinBoxValueChanged;
|
|
BufferTransferAmount.OnValueChanged += OnSpinBoxValueChanged;
|
|
EjectButton.OnPressed += _ => EjectButtonPressed?.Invoke();
|
|
AddReagentButton.OnPressed += OnAddReagentPressed;
|
|
ProduceButton.OnPressed += OnProducePressed;
|
|
ReagentAmount.OnValueChanged += OnSpinBoxValueChanged;
|
|
|
|
BeakerReagentSelector.OnItemSelected += OnBeakerReagentSelected;
|
|
BufferReagentSelector.OnItemSelected += OnBufferReagentSelected;
|
|
ReagentSelector.OnItemSelected += OnReagentSelected;
|
|
}
|
|
|
|
private void OnTransferToBufferPressed(BaseButton.ButtonEventArgs args)
|
|
{
|
|
if (BeakerReagentSelector.SelectedId == 0)
|
|
return;
|
|
|
|
var selectedHash = BeakerReagentSelector.SelectedId;
|
|
var selectedReagent = _beakerReagents.Keys.FirstOrDefault(id => id.Prototype.GetHashCode() == selectedHash);
|
|
|
|
var amount = FixedPoint2.New(BeakerTransferAmount.Value);
|
|
TransferToBufferPressed?.Invoke(selectedReagent, amount);
|
|
}
|
|
|
|
private void OnTransferToBeakerPressed(BaseButton.ButtonEventArgs args)
|
|
{
|
|
if (BufferReagentSelector.SelectedId == 0)
|
|
return;
|
|
|
|
var selectedHash = BufferReagentSelector.SelectedId;
|
|
var selectedReagent = _bufferReagents.Keys.FirstOrDefault(id => id.Prototype.GetHashCode() == selectedHash);
|
|
|
|
var amount = FixedPoint2.New(BufferTransferAmount.Value);
|
|
TransferToBeakerPressed?.Invoke(selectedReagent, amount);
|
|
}
|
|
|
|
private void OnAddReagentPressed(BaseButton.ButtonEventArgs args)
|
|
{
|
|
if (ReagentSelector.SelectedId == 0)
|
|
return;
|
|
|
|
var selectedHash = ReagentSelector.SelectedId;
|
|
var selectedReagent = _bufferReagents.Keys.FirstOrDefault(id => id.Prototype.GetHashCode() == selectedHash);
|
|
|
|
var amount = FixedPoint2.New(ReagentAmount.Value);
|
|
ReagentAdded?.Invoke(selectedReagent, amount);
|
|
}
|
|
|
|
private void OnProducePressed(BaseButton.ButtonEventArgs args)
|
|
{
|
|
var amount = ProductionAmount.Value;
|
|
var customName = string.IsNullOrWhiteSpace(CustomNameInput.Text) ? null : CustomNameInput.Text;
|
|
|
|
ProduceButtonPressed?.Invoke((int)amount, customName);
|
|
}
|
|
|
|
private void OnBeakerReagentSelected(OptionButton.ItemSelectedEventArgs args)
|
|
{
|
|
BeakerReagentSelector.SelectId(args.Id);
|
|
}
|
|
|
|
private void OnBufferReagentSelected(OptionButton.ItemSelectedEventArgs args)
|
|
{
|
|
BufferReagentSelector.SelectId(args.Id);
|
|
}
|
|
|
|
private void OnReagentSelected(OptionButton.ItemSelectedEventArgs args)
|
|
{
|
|
ReagentSelector.SelectId(args.Id);
|
|
}
|
|
|
|
public void UpdateState(InjectorFabticatorBoundUserInterfaceState state)
|
|
{
|
|
// Update beaker slot
|
|
if (state.Beaker == null)
|
|
{
|
|
BeakerSlot.RemoveAllChildren();
|
|
BeakerInfoLabel.Text = Loc.GetString("injector-fabticator-no-beaker");
|
|
}
|
|
else
|
|
{
|
|
var entityView = new SpriteView
|
|
{
|
|
Scale = new Vector2(2, 2),
|
|
SetSize = new Vector2(64, 64),
|
|
Margin = new Thickness(4)
|
|
};
|
|
entityView.SetEntity(_entityManager.GetEntity(state.Beaker));
|
|
BeakerSlot.AddChild(entityView);
|
|
|
|
if (state.BeakerContainerInfo != null)
|
|
{
|
|
BeakerInfoLabel.Text = $"{state.BeakerContainerInfo.DisplayName}: " +
|
|
$"{state.BeakerContainerInfo.CurrentVolume}/{state.BeakerContainerInfo.MaxVolume}";
|
|
UpdateReagentList(BeakerReagentList, state.BeakerContainerInfo.Reagents);
|
|
}
|
|
}
|
|
EjectButton.Disabled = state.Beaker == null;
|
|
|
|
// Update buffer solution
|
|
BufferProgress.Value = (float)(state.BufferVolume / state.BufferMaxVolume * 100);
|
|
UpdateReagentList(BufferReagentList, state.BufferSolution?.Contents);
|
|
|
|
// Update recipe
|
|
UpdateReagentList(RecipeReagentList, state.Recipe);
|
|
|
|
// Update reagent selectors
|
|
UpdateReagentSelectors(state);
|
|
|
|
// Update production controls
|
|
var canProduce = state.CanProduce && !state.IsProducing;
|
|
CustomNameInput.Editable = !state.IsProducing;
|
|
ProduceButton.Disabled = !canProduce;
|
|
|
|
// Update status
|
|
StatusLabel.Text = state.IsProducing
|
|
? Loc.GetString("injector-fabticator-status-producing",
|
|
("remaining", state.InjectorsToProduce - state.InjectorsProduced))
|
|
: Loc.GetString("injector-fabticator-status-ready");
|
|
}
|
|
|
|
private void UpdateReagentSelectors(InjectorFabticatorBoundUserInterfaceState state)
|
|
{
|
|
// Clear and update buffer reagents
|
|
_beakerReagents.Clear();
|
|
_bufferReagents.Clear();
|
|
ReagentSelector.Clear();
|
|
BufferReagentSelector.Clear();
|
|
BeakerReagentSelector.Clear();
|
|
|
|
// Add beaker reagents to beaker transfer selector
|
|
if (state.BeakerContainerInfo?.Reagents != null)
|
|
{
|
|
foreach (var reagent in state.BeakerContainerInfo.Reagents)
|
|
{
|
|
if (_prototypeManager.TryIndex<ReagentPrototype>(reagent.Reagent.Prototype, out var reagentProto))
|
|
{
|
|
_beakerReagents[reagent.Reagent] = reagentProto;
|
|
BeakerReagentSelector.AddItem(reagentProto.LocalizedName, reagent.Reagent.Prototype.GetHashCode());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add buffer reagents to selectors
|
|
if (state.BufferSolution?.Contents != null)
|
|
{
|
|
foreach (var (reagentId, _) in state.BufferSolution.Contents)
|
|
{
|
|
if (_prototypeManager.TryIndex<ReagentPrototype>(reagentId.Prototype, out var reagentProto))
|
|
{
|
|
_bufferReagents[reagentId] = reagentProto;
|
|
ReagentSelector.AddItem(reagentProto.LocalizedName, reagentId.Prototype.GetHashCode());
|
|
BufferReagentSelector.AddItem(reagentProto.LocalizedName, reagentId.Prototype.GetHashCode());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update transfer buttons state
|
|
TransferToBufferButton.Disabled = BeakerReagentSelector.ItemCount == 0;
|
|
TransferToBeakerButton.Disabled = BufferReagentSelector.ItemCount == 0;
|
|
AddReagentButton.Disabled = ReagentSelector.ItemCount == 0;
|
|
}
|
|
|
|
private void UpdateReagentList(BoxContainer container, IReadOnlyDictionary<ReagentId, FixedPoint2>? reagents)
|
|
{
|
|
if (reagents == null)
|
|
{
|
|
container.RemoveAllChildren();
|
|
container.AddChild(new Label { Text = Loc.GetString("injector-fabticator-empty") });
|
|
return;
|
|
}
|
|
|
|
// Convert dictionary to a list of ReagentQuantity
|
|
var reagentList = reagents.Select(x => new ReagentQuantity(x.Key, x.Value)).ToList();
|
|
UpdateReagentList(container, reagentList);
|
|
}
|
|
|
|
private void UpdateReagentList(BoxContainer container, IReadOnlyList<ReagentQuantity>? reagents)
|
|
{
|
|
container.RemoveAllChildren();
|
|
if (reagents == null || reagents.Count == 0)
|
|
{
|
|
container.AddChild(new Label { Text = Loc.GetString("injector-fabticator-empty") });
|
|
return;
|
|
}
|
|
|
|
var groupedReagents = reagents
|
|
.GroupBy(r => r.Reagent)
|
|
.Select(g => new
|
|
{
|
|
ReagentId = g.Key,
|
|
Quantity = g.Aggregate(FixedPoint2.Zero, (sum, x) => sum + x.Quantity),
|
|
Prototype = _prototypeManager.Index<ReagentPrototype>(g.Key.Prototype)
|
|
});
|
|
|
|
foreach (var reagent in groupedReagents)
|
|
{
|
|
var row = new BoxContainer
|
|
{
|
|
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
|
HorizontalExpand = true
|
|
};
|
|
|
|
row.AddChild(new Label
|
|
{
|
|
Text = reagent.Prototype.LocalizedName,
|
|
HorizontalExpand = true
|
|
});
|
|
|
|
row.AddChild(new Label
|
|
{
|
|
Text = $"{reagent.Quantity}u",
|
|
Align = Label.AlignMode.Right
|
|
});
|
|
|
|
if (container == RecipeReagentList)
|
|
{
|
|
var removeButton = new Button
|
|
{
|
|
Text = Loc.GetString("injector-fabticator-button-remove"),
|
|
MinWidth = 80,
|
|
Margin = new Thickness(5, 0, 0, 0)
|
|
};
|
|
|
|
removeButton.OnPressed += _ =>
|
|
ReagentRemoved?.Invoke(reagent.ReagentId);
|
|
|
|
row.AddChild(removeButton);
|
|
}
|
|
|
|
container.AddChild(row);
|
|
}
|
|
}
|
|
|
|
private void OnSpinBoxValueChanged(FloatSpinBox.FloatSpinBoxEventArgs args)
|
|
{
|
|
if (args.Value < 1)
|
|
{
|
|
args.Control.Value = 1;
|
|
}
|
|
else if (args.Value > 30)
|
|
{
|
|
args.Control.Value = 30;
|
|
}
|
|
}
|
|
}
|