diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index 7478e08..052f2eb 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -8,7 +8,7 @@ namespace ColdMint.scripts.inventory; /// item container /// 物品容器 /// -public interface IItemContainer : IEnumerable +public interface IItemContainer { /// /// This event is triggered when the selected item changes diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 0dfbde2..24e8969 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -1,8 +1,7 @@ using System; -using System.Collections; using System.Collections.Generic; +using ColdMint.scripts.debug; using ColdMint.scripts.map.events; -using JetBrains.Annotations; namespace ColdMint.scripts.inventory; @@ -12,7 +11,7 @@ namespace ColdMint.scripts.inventory; /// public class UniversalItemContainer(int totalCapacity) : IItemContainer { - private readonly List _itemList = []; + private readonly Dictionary _itemDictionary = []; /// /// UnknownIndex @@ -24,17 +23,15 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer //_selectIndex默认为0. private int _selectIndex; - [MustDisposeResource] - public IEnumerator GetEnumerator() - { - return _itemList.GetEnumerator(); - } - - [MustDisposeResource] - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } + /// + /// The next available index + /// 下个可用的索引 + /// + /// + ///For example, the variable [1,2,3,5,6] represents 4, or the variable [1,2,3,4,5,6,7] represents 8. + ///例如[1,2,3,5,6]这个变量表示4,再或者[1,2,3,4,5,6,7]这个变量表示8。 + /// + private int _nextAvailableIndex; public Action? SelectedItemChangeEvent { get; set; } public Action? ItemDataChangeEvent { get; set; } @@ -58,7 +55,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer //If the capacity is full, we calculate whether we can spread the new items evenly among the existing items. //如果容量占满了,我们计算是否能将新物品均摊在已有的物品内。 var unallocatedQuantity = item.Quantity; - foreach (var unitItem in _itemList) + foreach (var unitItem in _itemDictionary.Values) { var number = unitItem.MergeableItemCount(item, unallocatedQuantity); if (number == 0) @@ -81,23 +78,47 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer item.IsSelect = index == _selectIndex; } + /// + /// Update the next available index location + /// 更新下个可用的索引位置 + /// + private void UpdateNextAvailableIndex() + { + _nextAvailableIndex = UnknownIndex; + if (totalCapacity <= 0) + { + LogCat.Log("Next available item"+_nextAvailableIndex); + return; + } + for (var i = 0; i < totalCapacity; i++) + { + var contains = _itemDictionary.ContainsKey(i); + if (!contains) + { + _nextAvailableIndex = i; + LogCat.Log("Next available item"+_nextAvailableIndex); + return; + } + } + } + public int AddItem(IItem item) { if (item.MaxQuantity == 1) { - if (GetUsedCapacity() >= totalCapacity) + if (_nextAvailableIndex == UnknownIndex) { - //Items cannot be stacked and cannot be added if the capacity is full. - //物品不能叠加,且容量已满,则无法添加。 return 0; } - _itemList.Add(item); - UpdateSelectStatus(_itemList.Count - 1, item); + var nextAvailableIndex = _nextAvailableIndex; + _itemDictionary[nextAvailableIndex] = item; + UpdateNextAvailableIndex(); + UpdateSelectStatus(nextAvailableIndex, item); ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent { NewItem = item, - NewIndex = _itemList.Count - 1, + NewIndex = nextAvailableIndex, Type = Config.ItemDataChangeEventType.QuantityAdded }); return item.Quantity; @@ -107,7 +128,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer //物品可有多个,尝试均摊。 var originalQuantity = item.Quantity; var index = 0; - foreach (var unitItem in _itemList) + foreach (var unitItem in _itemDictionary.Values) { var number = unitItem.MergeableItemCount(item, item.Quantity); if (number == 0) @@ -144,12 +165,18 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer //Add the rest to the container. //添加剩余到容器内。 - _itemList.Add(item); - UpdateSelectStatus(_itemList.Count - 1, item); + if (_nextAvailableIndex == UnknownIndex) + { + return 0; + } + var finalNextAvailableIndex = _nextAvailableIndex; + _itemDictionary[finalNextAvailableIndex] = item; + UpdateNextAvailableIndex(); + UpdateSelectStatus(finalNextAvailableIndex, item); ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent { NewItem = item, - NewIndex = _itemList.Count - 1, + NewIndex = finalNextAvailableIndex, Type = Config.ItemDataChangeEventType.Add }); return originalQuantity; @@ -170,66 +197,14 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer public IItem? GetSelectItem() { - var count = _itemList.Count; - if (count == 0) - { - return null; - } - - return _selectIndex < count ? _itemList[_selectIndex] : null; + return _itemDictionary.TryGetValue(_selectIndex, out var item) ? item : null; } public IItem? GetItem(int index) { - return GetValidIndex(index) == UnknownIndex ? null : _itemList[index]; + return _itemDictionary.TryGetValue(index, out var item) ? item : null; } - /// - /// Get valid index - /// 获取有效的索引 - /// - /// - /// - ///Return -1 if the given index exceeds the valid range of the list, otherwise return the given index itself. - ///如果给定的索引超过了列表的有效范围,那么返回-1,否则返回给定的索引本身。 - /// - private int GetValidIndex(int index) - { - var count = _itemList.Count; - if (count == 0) - { - return UnknownIndex; - } - if (index >= count || index < 0) - { - return UnknownIndex; - } - return index; - } - - /// - /// Gets a normalized subscript index - /// 获取规范化的下标索引 - /// - /// - /// - /// The difference between this method and is that if the given index is out of range, the result will be returned after rounding. - /// 失败返回-1,成功返回不会导致下标越界的索引,此方法和区别是,如果给定的索引超出了范围,那么会将结果取余后返回。 - /// - private int GetNormalizeIndex(int index) - { - var count = _itemList.Count; - if (count == 0 || index < 0) - { - //Prevents the dividend from being 0 - //防止被除数为0 - return UnknownIndex; - } - - return index % count; - } - - public int RemoveSelectItem(int number) { return RemoveItem(_selectIndex, number); @@ -242,20 +217,19 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer return 0; } - var index = GetValidIndex(itemIndex); - if (index == UnknownIndex) + if (!_itemDictionary.TryGetValue(itemIndex, out var item)) { return 0; } - - var item = _itemList[index]; + var originalQuantity = item.Quantity; if (number < 0) { //If the number entered is less than 0, all items are removed. //输入的数量小于0,则移除全部物品。 item.Quantity = 0; - _itemList.RemoveAt(index); + _itemDictionary.Remove(itemIndex); + UpdateNextAvailableIndex(); return originalQuantity; } @@ -263,7 +237,8 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer item.Quantity -= removed; if (item.Quantity < 1) { - _itemList.RemoveAt(index); + _itemDictionary.Remove(itemIndex); + UpdateNextAvailableIndex(); } return removed; @@ -271,7 +246,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer public int GetUsedCapacity() { - return _itemList.Count; + return _itemDictionary.Count; } public int GetTotalCapacity() @@ -282,7 +257,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer public void SelectNextItem() { - var count = EnablePlaceholder ? totalCapacity : _itemList.Count; + var count = totalCapacity; if (count == 0) { return; @@ -300,7 +275,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer public void SelectPreviousItem() { - var count = EnablePlaceholder ? totalCapacity : _itemList.Count; + var count = totalCapacity; if (count == 0) { return; @@ -358,23 +333,10 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer public void SelectItem(int index) { - if (EnablePlaceholder) + if (totalCapacity == 0 || index < 0) { - if (totalCapacity == 0) - { - return; - } - PrivateSelectItem(_selectIndex, index % totalCapacity); - } - else - { - var safeIndex = GetNormalizeIndex(index); - if (safeIndex == UnknownIndex) - { - return; - } - - PrivateSelectItem(_selectIndex, safeIndex); + return; } + PrivateSelectItem(_selectIndex, index % totalCapacity); } } \ No newline at end of file