Fixed an issue where two items would be selected at the same time when the player picked up the item and re-selected it.

修复玩家捡起物品后,重新选中物品,会有两个物品同时被选择的问题。
This commit is contained in:
Cold-Mint 2024-09-25 21:56:54 +08:00
parent b7c3651462
commit b9a9349596
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
2 changed files with 53 additions and 56 deletions

View File

@ -1,5 +1,6 @@
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;
@ -9,7 +10,7 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
protected readonly List<IItemDisplay> ItemDisplayList = []; protected readonly List<IItemDisplay> ItemDisplayList = [];
private IItemContainer? _itemContainer; private IItemContainer? _itemContainer;
public void BindItemContainer(IItemContainer itemContainer) public async void BindItemContainer(IItemContainer itemContainer)
{ {
if (_itemContainer == itemContainer) if (_itemContainer == itemContainer)
{ {
@ -52,6 +53,7 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
} }
} }
await Task.Yield();
UpdateData(itemContainer, adjustedEndIndex); UpdateData(itemContainer, adjustedEndIndex);
} }
@ -62,8 +64,7 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
return; return;
} }
var usedCapacity = _itemContainer.GetUsedCapacity(); UpdateDataForSingleLocation(_itemContainer, itemDataChangeEvent.NewIndex);
UpdateDataForSingleLocation(_itemContainer, itemDataChangeEvent.NewIndex, usedCapacity);
} }
private void OnSelectedItemChangeEvent(SelectedItemChangeEvent selectedItemChangeEvent) private void OnSelectedItemChangeEvent(SelectedItemChangeEvent selectedItemChangeEvent)
@ -73,9 +74,8 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
return; return;
} }
var usedCapacity = _itemContainer.GetUsedCapacity(); UpdateDataForSingleLocation(_itemContainer, selectedItemChangeEvent.OldIndex);
UpdateDataForSingleLocation(_itemContainer, selectedItemChangeEvent.OldIndex, usedCapacity); UpdateDataForSingleLocation(_itemContainer, selectedItemChangeEvent.NewIndex);
UpdateDataForSingleLocation(_itemContainer, selectedItemChangeEvent.NewIndex, usedCapacity);
} }
/// <summary> /// <summary>
@ -100,26 +100,9 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
/// </param> /// </param>
private void UpdateData(IItemContainer itemContainer, int endIndex, int startIndex = 0) private void UpdateData(IItemContainer itemContainer, int endIndex, int startIndex = 0)
{ {
var usedCapacity = itemContainer.GetUsedCapacity();
for (var i = startIndex; i < endIndex; i++) for (var i = startIndex; i < endIndex; i++)
{ {
var itemDisplay = ItemDisplayList[i]; UpdateDataForSingleLocation(itemContainer,i);
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();
} }
} }
@ -129,24 +112,20 @@ public abstract class ItemContainerDisplayTemplate : IItemContainerDisplay
/// </summary> /// </summary>
/// <param name="itemContainer"></param> /// <param name="itemContainer"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="usedCapacity"></param> private void UpdateDataForSingleLocation(IItemContainer itemContainer, int index)
private void UpdateDataForSingleLocation(IItemContainer itemContainer, int index, int usedCapacity)
{ {
var itemDisplay = ItemDisplayList[index]; var itemDisplay = ItemDisplayList[index];
if (index < usedCapacity) var item = itemContainer.GetItem(index);
if (item == null)
{ {
itemDisplay.Update(itemContainer.GetItem(index)); item = itemContainer.GetPlaceHolderItem();
} }
else if (item != null)
{ {
var placeHolderItem = itemContainer.GetPlaceHolderItem(); item.IsSelect = index == itemContainer.GetSelectIndex();
if (placeHolderItem != null)
{
placeHolderItem.IsSelect = index == itemContainer.GetSelectIndex();
}
itemDisplay.Update(placeHolderItem);
} }
itemDisplay.Update(item);
itemDisplay.ShowSelf();
} }
/// <summary> /// <summary>

View File

@ -170,38 +170,56 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
public IItem? GetSelectItem() public IItem? GetSelectItem()
{ {
if (_itemList.Count == 0) var count = _itemList.Count;
if (count == 0)
{ {
return null; return null;
} }
return _selectIndex < _itemList.Count ? _itemList[_selectIndex] : null; return _selectIndex < count ? _itemList[_selectIndex] : null;
} }
public IItem? GetItem(int index) public IItem? GetItem(int index)
{ {
var safeIndex = GetSafeIndex(index); return GetValidIndex(index) == UnknownIndex ? null : _itemList[index];
if (safeIndex == UnknownIndex)
{
return null;
}
return _itemList[safeIndex];
} }
/// <summary> /// <summary>
/// <para>Gets a secure subscript index</para> /// <para>Get valid index</para>
/// <para>获取安全的下标索引</para> /// <para>获取有效的索引</para>
/// </summary> /// </summary>
/// <param name="index"></param> /// <param name="index"></param>
/// <returns> /// <returns>
/// <para>-1 is returned on failure, and the index that does not result in an out-of-bounds subscript is returned on success</para> ///<para>Return -1 if the given index exceeds the valid range of the list, otherwise return the given index itself.</para>
/// <para>失败返回-1成功返回不会导致下标越界的索引</para> ///<para>如果给定的索引超过了列表的有效范围,那么返回-1,否则返回给定的索引本身。</para>
/// </returns> /// </returns>
private int GetSafeIndex(int index) private int GetValidIndex(int index)
{ {
var count = _itemList.Count; var count = _itemList.Count;
if (count == 0) if (count == 0)
{
return UnknownIndex;
}
if (index >= count || index < 0)
{
return UnknownIndex;
}
return index;
}
/// <summary>
/// <para>Gets a normalized subscript index</para>
/// <para>获取规范化的下标索引</para>
/// </summary>
/// <param name="index"></param>
/// <returns>
/// <para>The difference between this method and <see cref="GetValidIndex"/> is that if the given index is out of range, the result will be returned after rounding.</para>
/// <para>失败返回-1成功返回不会导致下标越界的索引此方法和<see cref="GetValidIndex"/>区别是,如果给定的索引超出了范围,那么会将结果取余后返回。</para>
/// </returns>
private int GetNormalizeIndex(int index)
{
var count = _itemList.Count;
if (count == 0 || index < 0)
{ {
//Prevents the dividend from being 0 //Prevents the dividend from being 0
//防止被除数为0 //防止被除数为0
@ -224,20 +242,20 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
return 0; return 0;
} }
var safeIndex = GetSafeIndex(itemIndex); var index = GetValidIndex(itemIndex);
if (safeIndex == UnknownIndex) if (index == UnknownIndex)
{ {
return 0; return 0;
} }
var item = _itemList[safeIndex]; var item = _itemList[index];
var originalQuantity = item.Quantity; var originalQuantity = item.Quantity;
if (number < 0) if (number < 0)
{ {
//If the number entered is less than 0, all items are removed. //If the number entered is less than 0, all items are removed.
//输入的数量小于0,则移除全部物品。 //输入的数量小于0,则移除全部物品。
item.Quantity = 0; item.Quantity = 0;
_itemList.RemoveAt(safeIndex); _itemList.RemoveAt(index);
return originalQuantity; return originalQuantity;
} }
@ -245,7 +263,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
item.Quantity -= removed; item.Quantity -= removed;
if (item.Quantity < 1) if (item.Quantity < 1)
{ {
_itemList.RemoveAt(safeIndex); _itemList.RemoveAt(index);
} }
return removed; return removed;
@ -350,7 +368,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer
} }
else else
{ {
var safeIndex = GetSafeIndex(index); var safeIndex = GetNormalizeIndex(index);
if (safeIndex == UnknownIndex) if (safeIndex == UnknownIndex)
{ {
return; return;