diff --git a/scripts/Config.cs b/scripts/Config.cs index b271ac2..dfb3d06 100644 --- a/scripts/Config.cs +++ b/scripts/Config.cs @@ -170,6 +170,12 @@ public static class Config ///在禁用版本隔离时用的 /// public const string DefaultVersionName = "Default"; + + /// + /// EmptyVariant + /// 空变量 + /// + public static readonly Variant EmptyVariant = new(); /// @@ -231,7 +237,13 @@ public static class Config /// remove /// 移除 /// - Remove + Remove, + + /// + /// Replace + /// 被替换 + /// + Replace } public enum OsEnum diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index 826e57f..faa6cf8 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -789,7 +789,7 @@ public partial class CharacterTemplate : CharacterBody2D { return; } - + item.ItemContainer = null; NodeUtils.CallDeferredAddChild(NodeUtils.FindContainerNode(node2D, GetNode("/root")), node2D); switch (item) { diff --git a/scripts/inventory/IItem.cs b/scripts/inventory/IItem.cs index 4a63492..783091a 100644 --- a/scripts/inventory/IItem.cs +++ b/scripts/inventory/IItem.cs @@ -45,6 +45,12 @@ public interface IItem /// 是否选中 /// bool IsSelect { get; set; } + + /// + /// The container in which the item is located + /// 物品所在的物品容器 + /// + IItemContainer? ItemContainer { get; set; } /// /// Calculate how many items can be merged with other items diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index 052f2eb..c06f23d 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using ColdMint.scripts.map.events; namespace ColdMint.scripts.inventory; @@ -76,6 +75,21 @@ public interface IItemContainer /// IItem? GetItem(int index); + /// + /// ReplaceItem + /// 替换物品 + /// + /// + ///Even if the item corresponding to the index is null, it can be successfully replaced. + ///即使索引对应的物品为null,也可以成功的替换。 + /// + /// + /// + /// + bool ReplaceItem(int index, IItem item); + + bool ReplaceItem(IItem oldItem, IItem newItem); + /// /// Gets the item in the specified location, equivalent to /// 获取指定位置的物品,等同于 @@ -114,6 +128,14 @@ public interface IItemContainer /// int RemoveItem(int itemIndex, int number); + /// + /// Remove item + /// 移除物品 + /// + /// + /// + int RemoveItem(IItem item, int number); + /// /// Gets the used capacity of the item container /// 获取物品容器已使用的容量 diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index 34ce733..d413f85 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -32,9 +32,17 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay public override Variant _GetDragData(Vector2 atPosition) { + switch (Item) + { + case null: + return Config.EmptyVariant; + case PlaceholderItem: + return Config.EmptyVariant; + } + if (_iconTextureRect == null) { - return new Variant(); + return Config.EmptyVariant; } var textureRect = new TextureRect(); @@ -47,15 +55,25 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay public override bool _CanDropData(Vector2 atPosition, Variant data) { - if (Item == null) + var type = data.VariantType; + if (type == Variant.Type.Nil) { return false; } - if (Item is PlaceholderItem) + switch (Item) { - return false; + case null: + case PlaceholderItem: + return true; + default: + var itemSlotNode = data.As(); + var sourceItem = itemSlotNode.Item; + if (sourceItem == null) + { + return false; + } + return Item.MergeableItemCount(sourceItem, sourceItem.Quantity) > 0; } - return true; } public override void _DropData(Vector2 atPosition, Variant data) @@ -63,26 +81,21 @@ public partial class ItemSlotNode : MarginContainer, IItemDisplay var type = data.VariantType; if (type == Variant.Type.Nil) { - //The passed variable is null. - //传入的变量为null。 return; } var itemSlotNode = data.As(); var sourceItem = itemSlotNode.Item; if (sourceItem == null) { - //Return null when trying to get the source item. - //尝试获取源物品时返回null。 return; } + if (Item is null || Item is PlaceholderItem) + { + sourceItem.ItemContainer?.RemoveItem(sourceItem, -1); + Item?.ItemContainer?.ReplaceItem(Item, sourceItem); + } } - /// - /// Whether to place a backpack in the current slot - /// 当前槽位是否允许放置背包 - /// - public bool BackpackAllowed { get; set; } - private void UpdateBackground(bool isSelect) { diff --git a/scripts/inventory/PlaceholderItem.cs b/scripts/inventory/PlaceholderItem.cs index 1c747cc..6437dbd 100644 --- a/scripts/inventory/PlaceholderItem.cs +++ b/scripts/inventory/PlaceholderItem.cs @@ -15,6 +15,7 @@ public class PlaceholderItem : IItem public int Quantity { get; set; } = 1; public int MaxQuantity { get; } = 1; public bool IsSelect { get; set; } + public IItemContainer? ItemContainer { get; set; } public int MergeableItemCount(IItem other, int unallocatedQuantity) { diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 5bbd4da..e38e95c 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using ColdMint.scripts.debug; using ColdMint.scripts.map.events; namespace ColdMint.scripts.inventory; @@ -87,7 +86,6 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer _nextAvailableIndex = UnknownIndex; if (totalCapacity <= 0) { - LogCat.Log("Next available item"+_nextAvailableIndex); return; } for (var i = 0; i < totalCapacity; i++) @@ -96,7 +94,6 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer if (!contains) { _nextAvailableIndex = i; - LogCat.Log("Next available item"+_nextAvailableIndex); return; } } @@ -113,6 +110,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer var nextAvailableIndex = _nextAvailableIndex; _itemDictionary[nextAvailableIndex] = item; + item.ItemContainer = this; UpdateNextAvailableIndex(); UpdateSelectStatus(nextAvailableIndex, item); ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent @@ -171,6 +169,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer } var finalNextAvailableIndex = _nextAvailableIndex; _itemDictionary[finalNextAvailableIndex] = item; + item.ItemContainer = this; UpdateNextAvailableIndex(); UpdateSelectStatus(finalNextAvailableIndex, item); ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent @@ -205,6 +204,27 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer return _itemDictionary.TryGetValue(index, out var item) ? item : null; } + public bool ReplaceItem(int index, IItem item) + { + var oldItem = GetItem(index); + _itemDictionary[index] = item; + ItemDataChangeEvent?.Invoke(new ItemDataChangeEvent + { + NewItem = item, + NewIndex = index, + OldIndex = index, + OldItem = oldItem, + Type = Config.ItemDataChangeEventType.Replace + }); + return true; + } + + public bool ReplaceItem(IItem oldItem, IItem newItem) + { + var index = GetIndexByItem(oldItem); + return index != UnknownIndex && ReplaceItem(index, newItem); + } + public int RemoveSelectItem(int number) { return RemoveItem(_selectIndex, number); @@ -221,7 +241,7 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer { return 0; } - + var originalQuantity = item.Quantity; if (number < 0) { @@ -256,6 +276,37 @@ public class UniversalItemContainer(int totalCapacity) : IItemContainer return removed; } + public int RemoveItem(IItem item, int number) + { + var index = GetIndexByItem(item); + return index == UnknownIndex ? 0 : RemoveItem(index, number); + } + + + /// + /// Find the corresponding index based on the item object + /// 根据物品对象查找对应的索引 + /// + /// + /// + private int GetIndexByItem(IItem item) + { + if (totalCapacity <= 0) + { + return UnknownIndex; + } + for (var i = 0; i < totalCapacity; i++) + { + var contains = _itemDictionary.ContainsKey(i); + if (!contains) continue; + if (item == _itemDictionary[i]) + { + return i; + } + } + return UnknownIndex; + } + public int GetUsedCapacity() { return _itemDictionary.Count; diff --git a/scripts/pickable/PickAbleTemplate.cs b/scripts/pickable/PickAbleTemplate.cs index 83b61e4..f1a9985 100644 --- a/scripts/pickable/PickAbleTemplate.cs +++ b/scripts/pickable/PickAbleTemplate.cs @@ -78,6 +78,7 @@ public partial class PickAbleTemplate : RigidBody2D, IItem public int MaxQuantity { get; set; } = 1; public bool IsSelect { get; set; } + public IItemContainer? ItemContainer { get; set; } private Label? _tipLabel;