mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
TUI support for more container
This commit is contained in:
parent
ef133f3d6d
commit
0194380fbc
17 changed files with 2045 additions and 822 deletions
|
|
@ -1,152 +1,48 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using MinecraftClient.Inventory;
|
||||
|
||||
namespace MinecraftClient.Tui
|
||||
{
|
||||
public class InventoryViewModel : INotifyPropertyChanged
|
||||
public class PlayerInventoryViewModel : ContainerViewModel
|
||||
{
|
||||
private SlotViewModel? _hoveredSlot;
|
||||
private string _title = "";
|
||||
private string _statusText = "";
|
||||
private string _cursorItemInfo = "";
|
||||
private bool _hasCursorItem;
|
||||
|
||||
public McClient Handler { get; }
|
||||
public int WindowId { get; }
|
||||
|
||||
public ObservableCollection<SlotViewModel> EquipmentSlots { get; } = new();
|
||||
public ObservableCollection<SlotViewModel> CraftingInputSlots { get; } = new();
|
||||
public SlotViewModel CraftingOutputSlot { get; }
|
||||
public ObservableCollection<SlotViewModel> MainInventorySlots { get; } = new();
|
||||
public ObservableCollection<SlotViewModel> HotbarSlots { get; } = new();
|
||||
public SlotViewModel OffhandSlot { get; }
|
||||
|
||||
public string Title
|
||||
public PlayerInventoryViewModel(McClient handler, int windowId)
|
||||
: base(handler, windowId, ContainerType.PlayerInventory)
|
||||
{
|
||||
get => _title;
|
||||
set { _title = value; OnPropertyChanged(); }
|
||||
CraftingOutputSlot = SlotMap[0];
|
||||
OffhandSlot = SlotMap[45];
|
||||
}
|
||||
|
||||
public string StatusText
|
||||
protected override void InitializeSlots()
|
||||
{
|
||||
get => _statusText;
|
||||
set { _statusText = value; OnPropertyChanged(); }
|
||||
}
|
||||
SlotMap.Clear();
|
||||
|
||||
public string CursorItemInfo
|
||||
{
|
||||
get => _cursorItemInfo;
|
||||
set { _cursorItemInfo = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public bool HasCursorItem
|
||||
{
|
||||
get => _hasCursorItem;
|
||||
set { _hasCursorItem = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
public SlotViewModel? HoveredSlot
|
||||
{
|
||||
get => _hoveredSlot;
|
||||
set
|
||||
{
|
||||
if (_hoveredSlot != null)
|
||||
_hoveredSlot.IsHovered = false;
|
||||
_hoveredSlot = value;
|
||||
if (_hoveredSlot != null)
|
||||
_hoveredSlot.IsHovered = true;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(HoveredSlotDetailText));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multi-line detail text for the hovered slot.
|
||||
/// </summary>
|
||||
public string HoveredSlotDetailText
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hoveredSlot == null)
|
||||
return Translations.tui_inventory_hover_hint;
|
||||
|
||||
if (_hoveredSlot.IsEmpty)
|
||||
return $"Slot #{_hoveredSlot.SlotId}\n{Translations.tui_inventory_slot_empty}";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(_hoveredSlot.ItemTypeName);
|
||||
sb.AppendLine(string.Format(Translations.tui_inventory_slot_detail, _hoveredSlot.SlotId, _hoveredSlot.ItemCount));
|
||||
|
||||
string fullInfo = _hoveredSlot.FullInfo;
|
||||
if (!string.IsNullOrEmpty(fullInfo))
|
||||
{
|
||||
string[] parts = fullInfo.Split(" | ");
|
||||
for (int i = 1; i < parts.Length; i++)
|
||||
sb.AppendLine(parts[i].Trim());
|
||||
}
|
||||
|
||||
return sb.ToString().TrimEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<int, SlotViewModel> _slotMap = new();
|
||||
private int _nameMaxLen = 9;
|
||||
private int _nameMaxLines = 1;
|
||||
|
||||
public InventoryViewModel(McClient handler, int windowId)
|
||||
{
|
||||
Handler = handler;
|
||||
WindowId = windowId;
|
||||
|
||||
CraftingOutputSlot = new SlotViewModel(0);
|
||||
OffhandSlot = new SlotViewModel(45);
|
||||
|
||||
InitializeSlots();
|
||||
RefreshFromContainer();
|
||||
}
|
||||
|
||||
public void SetSlotDisplayParams(int maxWidth, int maxLines)
|
||||
{
|
||||
_nameMaxLen = maxWidth;
|
||||
_nameMaxLines = maxLines;
|
||||
foreach (var kvp in _slotMap)
|
||||
{
|
||||
kvp.Value.NameMaxWidth = maxWidth;
|
||||
kvp.Value.NameMaxLines = maxLines;
|
||||
}
|
||||
RefreshFromContainer();
|
||||
}
|
||||
|
||||
private void InitializeSlots()
|
||||
{
|
||||
_slotMap.Clear();
|
||||
|
||||
_slotMap[0] = CraftingOutputSlot;
|
||||
var craftOut = new SlotViewModel(0);
|
||||
SlotMap[0] = craftOut;
|
||||
|
||||
for (int i = 1; i <= 4; i++)
|
||||
{
|
||||
var slot = new SlotViewModel(i);
|
||||
CraftingInputSlots.Add(slot);
|
||||
_slotMap[i] = slot;
|
||||
SlotMap[i] = slot;
|
||||
}
|
||||
|
||||
for (int i = 5; i <= 8; i++)
|
||||
{
|
||||
var slot = new SlotViewModel(i);
|
||||
EquipmentSlots.Add(slot);
|
||||
_slotMap[i] = slot;
|
||||
SlotMap[i] = slot;
|
||||
}
|
||||
|
||||
for (int i = 9; i <= 35; i++)
|
||||
{
|
||||
var slot = new SlotViewModel(i);
|
||||
MainInventorySlots.Add(slot);
|
||||
_slotMap[i] = slot;
|
||||
SlotMap[i] = slot;
|
||||
}
|
||||
|
||||
for (int i = 36; i <= 44; i++)
|
||||
|
|
@ -154,67 +50,11 @@ namespace MinecraftClient.Tui
|
|||
int hotbarIdx = i - 36;
|
||||
var slot = new SlotViewModel(i, isHotbar: true, hotbarIndex: hotbarIdx);
|
||||
HotbarSlots.Add(slot);
|
||||
_slotMap[i] = slot;
|
||||
SlotMap[i] = slot;
|
||||
}
|
||||
|
||||
_slotMap[45] = OffhandSlot;
|
||||
}
|
||||
|
||||
public void RefreshFromContainer()
|
||||
{
|
||||
Inventory.Container? container = Handler.GetInventory(WindowId);
|
||||
if (container == null)
|
||||
{
|
||||
StatusText = Translations.tui_inventory_container_not_found;
|
||||
return;
|
||||
}
|
||||
|
||||
Title = string.Format(Translations.tui_inventory_title, WindowId, container.Title);
|
||||
|
||||
foreach (var kvp in _slotMap)
|
||||
{
|
||||
Item? item = container.Items.TryGetValue(kvp.Key, out var it) ? it : null;
|
||||
kvp.Value.Update(item);
|
||||
}
|
||||
|
||||
UpdateCursorItem(container);
|
||||
int itemCount = 0;
|
||||
foreach (var kvp in container.Items)
|
||||
{
|
||||
if (kvp.Key >= 0 && !kvp.Value.IsEmpty)
|
||||
itemCount++;
|
||||
}
|
||||
StatusText = string.Format(Translations.tui_inventory_item_count, itemCount);
|
||||
|
||||
OnPropertyChanged(nameof(HoveredSlotDetailText));
|
||||
}
|
||||
|
||||
private void UpdateCursorItem(Inventory.Container container)
|
||||
{
|
||||
if (container.Items.TryGetValue(-1, out var cursorItem) && !cursorItem.IsEmpty)
|
||||
{
|
||||
CursorItemInfo = $"x{cursorItem.Count} {cursorItem.GetTypeString()}";
|
||||
HasCursorItem = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CursorItemInfo = "";
|
||||
HasCursorItem = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool PerformAction(int slotId, WindowActionType action)
|
||||
{
|
||||
bool result = Handler.DoWindowAction(WindowId, slotId, action);
|
||||
RefreshFromContainer();
|
||||
return result;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private void OnPropertyChanged([CallerMemberName] string? name = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
var offhand = new SlotViewModel(45);
|
||||
SlotMap[45] = offhand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue