Ui/Inventory/InventorySelectUi.razor.cs
using System;
using System.Threading.Tasks;
using Clover.Inventory;
using Clover.Persistence;
using Clover.Player;
namespace Clover.Ui;
public partial class InventorySelectUi
{
private InventoryContainer Inventory => PlayerCharacter.Local?.Inventory.Container;
private readonly HashSet<int> _selectedItemIndexes = new();
public int MaxItems { get; set; } = 1;
public delegate bool CanSelectItemDelegate( InventorySlot slot );
[Property] public CanSelectItemDelegate CanSelectItem { get; set; }
public Action<HashSet<int>> OnSelect { get; set; }
public Action OnCancel { get; set; }
private TaskCompletionSource<HashSet<int>> _selectTaskCompletionSource;
public async Task<HashSet<int>> SelectItems( int maxItems, CanSelectItemDelegate canSelectItem )
{
Log.Info( $"SelectItems setup: {maxItems}" );
_selectTaskCompletionSource = new TaskCompletionSource<HashSet<int>>();
Open( maxItems, canSelectItem, OnSelectTask, OnCancelTask );
return await _selectTaskCompletionSource.Task;
}
private void OnSelectTask( HashSet<int> indexes )
{
_selectTaskCompletionSource.SetResult( indexes );
}
private void OnCancelTask()
{
_selectTaskCompletionSource.SetResult( new HashSet<int>() ); // TODO: null doesn't play nice with actiongraph
}
private void ToggleItem( int index )
{
if ( CanSelectItem != null && !CanSelectItem( Inventory.GetSlotByIndex( index ) ) )
{
PlayerCharacter.Local.Notify( Notifications.NotificationType.Error, "You can't select this item" );
return;
}
if ( _selectedItemIndexes.Contains( index ) )
{
_selectedItemIndexes.Remove( index );
return;
}
if ( _selectedItemIndexes.Count >= MaxItems )
{
if ( MaxItems == 1 )
{
_selectedItemIndexes.Clear();
_selectedItemIndexes.Add( index );
}
else
{
PlayerCharacter.Local.Notify( Notifications.NotificationType.Error, "You can't select more items" );
}
return;
}
if ( !_selectedItemIndexes.Add( index ) )
{
_selectedItemIndexes.Remove( index );
}
}
private void Select()
{
if ( _selectedItemIndexes.Count == 0 )
{
PlayerCharacter.Local.Notify( Notifications.NotificationType.Error, "You must select at least one item" );
return;
}
OnSelect?.Invoke( _selectedItemIndexes );
ResetSelection();
Enabled = false;
}
private void Cancel()
{
OnCancel?.Invoke();
ResetSelection();
Enabled = false;
}
private void ResetSelection()
{
_selectedItemIndexes.Clear();
OnSelect = null;
OnCancel = null;
}
private void Open( int maxItems, CanSelectItemDelegate canSelectItem, Action<HashSet<int>> onSelect,
Action onCancel )
{
Log.Info( $"Opening inventory select ui: {maxItems}" );
_selectedItemIndexes.Clear();
Enabled = true;
MaxItems = maxItems;
CanSelectItem = canSelectItem;
OnSelect = onSelect;
OnCancel = onCancel;
// await Task.Delay( 1 );
StateHasChanged();
}
/// <summary>
/// the hash determines if the system should be rebuilt. If it changes, it will be rebuilt
/// </summary>
protected override int BuildHash() =>
HashCode.Combine( Enabled, MaxItems, CanSelectItem, OnSelect, OnCancel, _selectedItemIndexes );
}