Use placeholders to resolve the problem that an empty slot cannot be selected in the shortcut bar.

使用占位符来解决快捷栏无法选中空槽位的问题。
This commit is contained in:
Cold-Mint 2024-09-23 23:17:57 +08:00
parent 63680a9410
commit b7c3651462
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
6 changed files with 100 additions and 24 deletions

View File

@ -15,7 +15,11 @@ public partial class HotBar : HBoxContainer
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_itemContainer = new UniversalItemContainer(Config.HotBarSize); var universalItemContainer = new UniversalItemContainer(Config.HotBarSize)
{
EnablePlaceholder = true
};
_itemContainer = universalItemContainer;
_itemContainer.SupportSelect = true; _itemContainer.SupportSelect = true;
_itemContainerDisplay = new ItemSlotContainerDisplay(this); _itemContainerDisplay = new ItemSlotContainerDisplay(this);
_itemContainerDisplay.BindItemContainer(_itemContainer); _itemContainerDisplay.BindItemContainer(_itemContainer);

View File

@ -47,6 +47,12 @@ public interface IItemContainer : IEnumerable<IItem>
/// </summary> /// </summary>
public bool SupportSelect { get; set; } public bool SupportSelect { get; set; }
/// <summary>
/// <para>Gets a placeholder object</para>
/// <para>获取占位符对象</para>
/// </summary>
/// <returns></returns>
IItem? GetPlaceHolderItem();
/// <summary> /// <summary>
/// <para>Gets the selected location</para> /// <para>Gets the selected location</para>

View File

@ -1,6 +1,5 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.events;
namespace ColdMint.scripts.inventory; namespace ColdMint.scripts.inventory;
@ -105,7 +104,21 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
for (var i = startIndex; i < endIndex; i++) for (var i = startIndex; i < endIndex; i++)
{ {
var itemDisplay = ItemDisplayList[i]; var itemDisplay = ItemDisplayList[i];
itemDisplay.Update(i < usedCapacity ? itemContainer.GetItem(i) : null); if (i < usedCapacity)
{
itemDisplay.Update(itemContainer.GetItem(i));
}
else
{
var placeHolderItem = itemContainer.GetPlaceHolderItem();
if (placeHolderItem != null)
{
placeHolderItem.IsSelect = i == itemContainer.GetSelectIndex();
}
itemDisplay.Update(placeHolderItem);
}
itemDisplay.ShowSelf(); itemDisplay.ShowSelf();
} }
} }
@ -120,7 +133,20 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
private void UpdateDataForSingleLocation(IItemContainer itemContainer, int index, int usedCapacity) private void UpdateDataForSingleLocation(IItemContainer itemContainer, int index, int usedCapacity)
{ {
var itemDisplay = ItemDisplayList[index]; var itemDisplay = ItemDisplayList[index];
itemDisplay.Update(index < usedCapacity ? itemContainer.GetItem(index) : null); if (index < usedCapacity)
{
itemDisplay.Update(itemContainer.GetItem(index));
}
else
{
var placeHolderItem = itemContainer.GetPlaceHolderItem();
if (placeHolderItem != null)
{
placeHolderItem.IsSelect = index == itemContainer.GetSelectIndex();
}
itemDisplay.Update(placeHolderItem);
}
} }
/// <summary> /// <summary>

View File

@ -1,4 +1,4 @@
using ColdMint.scripts.pickable; using ColdMint.scripts.pickable;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
using PacksackUi = ColdMint.scripts.loader.uiLoader.PacksackUi; using PacksackUi = ColdMint.scripts.loader.uiLoader.PacksackUi;

View File

@ -3,8 +3,8 @@ using Godot;
namespace ColdMint.scripts.inventory; namespace ColdMint.scripts.inventory;
/// <summary> /// <summary>
/// <para>A blank item used to occupy a space in the display. The IsSelect property is set to true so that the item display always appears selected when drawn.</para> /// <para>PlaceholderItem</para>
/// <para>物品容器显示器内用于占位的空白物品。IsSelect属性设置为true使得物品显示器绘制时总是显示为选中状态。</para> /// <para>占位物品</para>
/// </summary> /// </summary>
public class PlaceholderItem : IItem public class PlaceholderItem : IItem
{ {
@ -14,7 +14,7 @@ public class PlaceholderItem : IItem
public string? Description { get; } = null; public string? Description { get; } = null;
public int Quantity { get; set; } = 1; public int Quantity { get; set; } = 1;
public int MaxQuantity { get; } = 1; public int MaxQuantity { get; } = 1;
public bool IsSelect { get; set; } = true; public bool IsSelect { get; set; }
public int MergeableItemCount(IItem other, int unallocatedQuantity) public int MergeableItemCount(IItem other, int unallocatedQuantity)
{ {

View File

@ -43,7 +43,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
{ {
//If the capacity is not full, directly return to add items //If the capacity is not full, directly return to add items
//如果未占满容量,直接返回可添加物品 //如果未占满容量,直接返回可添加物品
if (GetUsedCapacity() < GetTotalCapacity()) if (GetUsedCapacity() < totalCapacity)
{ {
return true; return true;
} }
@ -76,12 +76,16 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
return unallocatedQuantity < 1; return unallocatedQuantity < 1;
} }
private void UpdateSelectStatus(int index, IItem item)
{
item.IsSelect = index == _selectIndex;
}
public int AddItem(IItem item) public int AddItem(IItem item)
{ {
if (item.MaxQuantity == 1) if (item.MaxQuantity == 1)
{ {
if (GetUsedCapacity() >= GetTotalCapacity()) if (GetUsedCapacity() >= totalCapacity)
{ {
//Items cannot be stacked and cannot be added if the capacity is full. //Items cannot be stacked and cannot be added if the capacity is full.
//物品不能叠加,且容量已满,则无法添加。 //物品不能叠加,且容量已满,则无法添加。
@ -89,6 +93,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
} }
_itemList.Add(item); _itemList.Add(item);
UpdateSelectStatus(_itemList.Count - 1, item);
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{ {
NewItem = item, NewItem = item,
@ -130,7 +135,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
//New items have some left over. //New items have some left over.
//新物品有一些剩余。 //新物品有一些剩余。
if (GetUsedCapacity() >= GetTotalCapacity()) if (GetUsedCapacity() >= totalCapacity)
{ {
//The capacity is full. The remaining capacity cannot be stored. //The capacity is full. The remaining capacity cannot be stored.
//容量已满,无法存放剩余。 //容量已满,无法存放剩余。
@ -140,6 +145,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
//Add the rest to the container. //Add the rest to the container.
//添加剩余到容器内。 //添加剩余到容器内。
_itemList.Add(item); _itemList.Add(item);
UpdateSelectStatus(_itemList.Count - 1, item);
ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent
{ {
NewItem = item, NewItem = item,
@ -150,6 +156,12 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
} }
public bool SupportSelect { get; set; } public bool SupportSelect { get; set; }
public bool EnablePlaceholder { get; set; }
public IItem? GetPlaceHolderItem()
{
return EnablePlaceholder ? new PlaceholderItem() : null;
}
public int GetSelectIndex() public int GetSelectIndex()
{ {
@ -158,7 +170,12 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
public IItem? GetSelectItem() public IItem? GetSelectItem()
{ {
return _itemList.Count == 0 ? null : _itemList[_selectIndex]; if (_itemList.Count == 0)
{
return null;
}
return _selectIndex < _itemList.Count ? _itemList[_selectIndex] : null;
} }
public IItem? GetItem(int index) public IItem? GetItem(int index)
@ -247,7 +264,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
public void SelectNextItem() public void SelectNextItem()
{ {
var count = _itemList.Count; var count = EnablePlaceholder ? totalCapacity : _itemList.Count;
if (count == 0) if (count == 0)
{ {
return; return;
@ -257,7 +274,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
var newSelectIndex = _selectIndex + 1; var newSelectIndex = _selectIndex + 1;
if (newSelectIndex >= count) if (newSelectIndex >= count)
{ {
newSelectIndex = count - 1; newSelectIndex = 0;
} }
PrivateSelectItem(oldSelectIndex, newSelectIndex); PrivateSelectItem(oldSelectIndex, newSelectIndex);
@ -265,7 +282,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
public void SelectPreviousItem() public void SelectPreviousItem()
{ {
var count = _itemList.Count; var count = EnablePlaceholder ? totalCapacity : _itemList.Count;
if (count == 0) if (count == 0)
{ {
return; return;
@ -294,10 +311,23 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
return; return;
} }
var oldItem = _itemList[oldIndex]; //There is no need to broadcast placeholders when an event is invoked.
//在调用事件时,无需广播占位符。
var oldItem = GetItem(oldIndex);
if (oldItem != null)
{
oldItem.IsSelect = false; oldItem.IsSelect = false;
var newItem = _itemList[newIndex]; }
//There is no need to broadcast placeholders when an event is invoked.
//在调用事件时,无需广播占位符。
var newItem = GetItem(newIndex);
if (newItem != null)
{
newItem.IsSelect = true; newItem.IsSelect = true;
}
_selectIndex = newIndex;
SelectedItemChangeEvent?.Invoke(new SelectedItemChangeEvent SelectedItemChangeEvent?.Invoke(new SelectedItemChangeEvent
{ {
NewIndex = newIndex, NewIndex = newIndex,
@ -305,11 +335,20 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
NewItem = newItem, NewItem = newItem,
OldItem = oldItem OldItem = oldItem
}); });
_selectIndex = newIndex;
} }
public void SelectItem(int index) public void SelectItem(int index)
{
if (EnablePlaceholder)
{
if (totalCapacity == 0)
{
return;
}
PrivateSelectItem(_selectIndex, index % totalCapacity);
}
else
{ {
var safeIndex = GetSafeIndex(index); var safeIndex = GetSafeIndex(index);
if (safeIndex == UnknownIndex) if (safeIndex == UnknownIndex)
@ -319,4 +358,5 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
PrivateSelectItem(_selectIndex, safeIndex); PrivateSelectItem(_selectIndex, safeIndex);
} }
}
} }