Make vending machine use EntityPrototypeView (#30064)

* Make vendor machines use EntityPrototypeView

* Update

* 1

* Kill me

* For the love of god!!!
This commit is contained in:
Winkarst
2024-08-22 17:40:39 +03:00
committed by GitHub
parent 5139ecdbd2
commit 588661465a
5 changed files with 109 additions and 98 deletions

View File

@@ -1,14 +1,13 @@
using System.Numerics;
using Content.Shared.VendingMachines;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
using Content.Shared.IdentityManagement;
using Robust.Shared.Timing;
using Robust.Client.UserInterface;
using Content.Client.UserInterface.Controls;
using Robust.Client.Graphics;
namespace Content.Client.VendingMachines.UI
{
@@ -16,12 +15,10 @@ namespace Content.Client.VendingMachines.UI
public sealed partial class VendingMachineMenu : FancyWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
private readonly Dictionary<EntProtoId, EntityUid> _dummies = [];
public event Action<GUIBoundKeyEventArgs, ListData>? OnItemSelected;
public event Action<ItemList.ItemListSelectedEventArgs>? OnItemSelected;
public event Action<string>? OnSearchChanged;
private readonly StyleBoxFlat _styleBox = new() { BackgroundColor = new Color(70, 73, 102) };
public VendingMachineMenu()
{
@@ -29,106 +26,90 @@ namespace Content.Client.VendingMachines.UI
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
SearchBar.OnTextChanged += _ =>
{
OnSearchChanged?.Invoke(SearchBar.Text);
};
VendingContents.OnItemSelected += args =>
{
OnItemSelected?.Invoke(args);
};
VendingContents.SearchBar = SearchBar;
VendingContents.DataFilterCondition += DataFilterCondition;
VendingContents.GenerateItem += GenerateButton;
VendingContents.ItemKeyBindDown += (args, data) => OnItemSelected?.Invoke(args, data);
}
protected override void Dispose(bool disposing)
private bool DataFilterCondition(string filter, ListData data)
{
base.Dispose(disposing);
if (data is not VendorItemsListData { ItemText: var text })
return false;
// Don't clean up dummies during disposal or we'll just have to spawn them again
if (!disposing)
if (string.IsNullOrEmpty(filter))
return true;
return text.Contains(filter, StringComparison.CurrentCultureIgnoreCase);
}
private void GenerateButton(ListData data, ListContainerButton button)
{
if (data is not VendorItemsListData { ItemProtoID: var protoID, ItemText: var text })
return;
// Delete any dummy items we spawned
foreach (var entity in _dummies.Values)
{
_entityManager.QueueDeleteEntity(entity);
}
_dummies.Clear();
button.AddChild(new VendingMachineItem(protoID, text));
button.ToolTip = text;
button.StyleBoxOverride = _styleBox;
}
/// <summary>
/// Populates the list of available items on the vending machine interface
/// and sets icons based on their prototypes
/// </summary>
public void Populate(List<VendingMachineInventoryEntry> inventory, out List<int> filteredInventory, string? filter = null)
public void Populate(List<VendingMachineInventoryEntry> inventory)
{
filteredInventory = new();
if (inventory.Count == 0)
if (inventory.Count == 0 && VendingContents.Visible)
{
VendingContents.Clear();
var outOfStockText = Loc.GetString("vending-machine-component-try-eject-out-of-stock");
VendingContents.AddItem(outOfStockText);
SetSizeAfterUpdate(outOfStockText.Length, VendingContents.Count);
SearchBar.Visible = false;
VendingContents.Visible = false;
var outOfStockLabel = new Label()
{
Text = Loc.GetString("vending-machine-component-try-eject-out-of-stock"),
Margin = new Thickness(4, 4),
HorizontalExpand = true,
VerticalAlignment = VAlignment.Stretch,
HorizontalAlignment = HAlignment.Center
};
MainContainer.AddChild(outOfStockLabel);
SetSizeAfterUpdate(outOfStockLabel.Text.Length, 0);
return;
}
while (inventory.Count != VendingContents.Count)
{
if (inventory.Count > VendingContents.Count)
VendingContents.AddItem(string.Empty);
else
VendingContents.RemoveAt(VendingContents.Count - 1);
}
var longestEntry = string.Empty;
var spriteSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>();
var listData = new List<VendorItemsListData>();
var filterCount = 0;
for (var i = 0; i < inventory.Count; i++)
{
var entry = inventory[i];
var vendingItem = VendingContents[i - filterCount];
vendingItem.Text = string.Empty;
vendingItem.Icon = null;
if (!_dummies.TryGetValue(entry.ID, out var dummy))
{
dummy = _entityManager.Spawn(entry.ID);
_dummies.Add(entry.ID, dummy);
}
var itemName = Identity.Name(dummy, _entityManager);
Texture? icon = null;
if (_prototypeManager.TryIndex<EntityPrototype>(entry.ID, out var prototype))
{
icon = spriteSystem.GetPrototypeIcon(prototype).Default;
}
// search filter
if (!string.IsNullOrEmpty(filter) &&
!itemName.ToLowerInvariant().Contains(filter.Trim().ToLowerInvariant()))
{
VendingContents.Remove(vendingItem);
filterCount++;
if (!_prototypeManager.TryIndex(entry.ID, out var prototype))
continue;
}
if (itemName.Length > longestEntry.Length)
longestEntry = itemName;
var itemText = $"{prototype.Name} [{entry.Amount}]";
vendingItem.Text = $"{itemName} [{entry.Amount}]";
vendingItem.Icon = icon;
filteredInventory.Add(i);
if (itemText.Length > longestEntry.Length)
longestEntry = itemText;
listData.Add(new VendorItemsListData(prototype.ID, itemText, i));
}
VendingContents.PopulateList(listData);
SetSizeAfterUpdate(longestEntry.Length, inventory.Count);
}
private void SetSizeAfterUpdate(int longestEntryLength, int contentCount)
{
SetSize = new Vector2(Math.Clamp((longestEntryLength + 2) * 12, 250, 300),
SetSize = new Vector2(Math.Clamp((longestEntryLength + 2) * 12, 250, 400),
Math.Clamp(contentCount * 50, 150, 350));
}
}
}
public record VendorItemsListData(EntProtoId ItemProtoID, string ItemText, int ItemIndex) : ListData;