From e5664f1553ba167d25d2c2e4233b0fc8d49a0475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Fri, 14 Jun 2024 12:22:44 +0800 Subject: [PATCH 1/3] =?UTF-8?q?Add=20PacksackStack=20for=20item=20Packsack?= =?UTF-8?q?=20=E4=B8=BAPacksack=E7=89=A9=E5=93=81=E6=B7=BB=E5=8A=A0Packsac?= =?UTF-8?q?kStack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/inventory/IItemContainer.cs | 23 ++++++-- scripts/inventory/ItemSlotNode.cs | 39 +++++++++---- scripts/inventory/UniversalItemContainer.cs | 18 ++++-- scripts/item/Packsack.cs | 20 ++++--- scripts/item/itemStacks/IItemStack.cs | 2 +- scripts/item/itemStacks/PacksackStack.cs | 63 +++++++++++++++++++++ 6 files changed, 133 insertions(+), 32 deletions(-) create mode 100644 scripts/item/itemStacks/PacksackStack.cs diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index a02e732..72ee577 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -34,6 +34,17 @@ public interface IItemContainer : IEnumerable /// bool AddItem(IItem item); + /// + /// Determines the number of items that can be received from the specified pile + /// 判断能从指定物品堆中接收的物品数量 + /// + /// + /// Item stack to add to the current container + /// 向该容器中放入物品的物品堆 + /// + /// + int CanAddItemStack(IItemStack itemStack); + /// /// Add an stack of items to this container /// 向当前容器中存入一堆物品 @@ -179,8 +190,8 @@ public interface IItemContainer : IEnumerable ItemSlotNode? Match(IItemStack stack); /// - /// Match the first item slot that has item stack that satisfies the predicate - /// 匹配首个拥有满足指定条件的物品堆的物品槽 + /// Match the first item slot that satisfies the predicate + /// 匹配首个拥有满足指定条件的物品槽 /// /// /// @@ -188,11 +199,11 @@ public interface IItemContainer : IEnumerable /// 若没有满足条件的槽位,返回null /// /// - ItemSlotNode? Match(Func predicate); + ItemSlotNode? Match(Func predicate); /// - /// Match all item slots that has item stack that satisfies the predicate - /// 匹配所有拥有满足指定条件的物品堆的物品槽 + /// Match all item slots that satisfies the predicate + /// 匹配所有拥有满足指定条件的物品槽 /// /// /// @@ -200,7 +211,7 @@ public interface IItemContainer : IEnumerable /// 包含匹配到的槽位的IEnumerable,当没有满足条件的槽位时为空 /// /// - IEnumerable MatchAll(Func predicate); + IEnumerable MatchAll(Func predicate); /// diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs index 5425825..2f34170 100644 --- a/scripts/inventory/ItemSlotNode.cs +++ b/scripts/inventory/ItemSlotNode.cs @@ -144,18 +144,6 @@ public partial class ItemSlotNode : MarginContainer UpdateAllDisplay(); } - /// - /// Can the specified item be placed in the item slot? - /// 指定的物品是否可设置在物品槽内? - /// - /// - /// - public bool CanAddItem(IItem item) - { - if (_itemStack == null) return true; - return _itemStack.CanAddItem(item); - } - /// /// /// Set item stack for this slot, this will completely replace current item stack. @@ -177,6 +165,18 @@ public partial class ItemSlotNode : MarginContainer return result; } + /// + /// Can the specified item be placed in the item slot? + /// 指定的物品是否可设置在物品槽内? + /// + /// + /// + public bool CanAddItem(IItem item) + { + if (_itemStack == null) return true; + return _itemStack.CanAddItem(item); + } + /// /// Try to add an item to this slot, if it can't be added to this slot, return false /// 尝试向当前槽位中加入物品,如果该物品不能被放入该槽位,返回false @@ -202,6 +202,21 @@ public partial class ItemSlotNode : MarginContainer return result; } + /// + /// Determines the number of items that can be received from the specified pile + /// 判断能从指定物品堆中接收的物品数量 + /// + /// + /// Item stack to add to the current slot + /// 向该物品槽中放入物品的物品堆 + /// + /// + public int CanAddItemStack(IItemStack itemStack) + { + if (_itemStack is null) return itemStack.Quantity; + return _itemStack.CanTakeFrom(itemStack); + } + /// /// Try to combine an item stack into this slot /// 尝试将一个物品堆合并至该槽位中 diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 8605b03..938f094 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -55,6 +55,16 @@ public class UniversalItemContainer : IItemContainer return itemSlotNode.AddItem(item); } + public int CanAddItemStack(IItemStack itemStack) + { + var testItem = itemStack.GetItem(); + if (testItem is null) return 0; + var slots = MatchAll(slot => slot.CanAddItem(testItem)); + return + Math.Min(itemStack.Quantity, + slots.Select(slot => slot.CanAddItemStack(itemStack)).Sum()); + } + public bool AddItemStack(IItemStack itemStack) { while (true) @@ -169,14 +179,14 @@ public class UniversalItemContainer : IItemContainer return _itemSlotNodes?.FirstOrDefault(itemSlotNode => itemSlotNode.CanAddItem(stack.GetItem()!)); } - public ItemSlotNode? Match(Func predicate) + public ItemSlotNode? Match(Func predicate) { - return _itemSlotNodes?.FirstOrDefault(node => predicate(node.GetItemStack())); + return _itemSlotNodes?.FirstOrDefault(predicate); } - public IEnumerable MatchAll(Func predicate) + public IEnumerable MatchAll(Func predicate) { - return from node in _itemSlotNodes where predicate(node.GetItemStack()) select node; + return from node in _itemSlotNodes where predicate(node) select node; } diff --git a/scripts/item/Packsack.cs b/scripts/item/Packsack.cs index 1afc8b0..6a9aa16 100644 --- a/scripts/item/Packsack.cs +++ b/scripts/item/Packsack.cs @@ -1,4 +1,5 @@ using ColdMint.scripts.inventory; +using ColdMint.scripts.item.itemStacks; using Godot; @@ -25,8 +26,8 @@ public partial class Packsack : RigidBody2D, IItem public void Destroy() { - if (_itemContainer == null) return; - foreach (var itemSlot in _itemContainer) + if (ItemContainer == null) return; + foreach (var itemSlot in ItemContainer) { itemSlot.ClearSlot(); } @@ -36,16 +37,17 @@ public partial class Packsack : RigidBody2D, IItem public bool CanStackWith(IItem item) => false; - private IItemContainer? _itemContainer; + public IItemStack? SpecialStack() + { + return new PacksackStack(this); + } + + + public IItemContainer? ItemContainer { get; private set; } public override void _Ready() { base._Ready(); - _itemContainer = new UniversalItemContainer(); - } - - public IItemContainer? GetItemContainer() - { - return _itemContainer; + ItemContainer = new UniversalItemContainer(); } } \ No newline at end of file diff --git a/scripts/item/itemStacks/IItemStack.cs b/scripts/item/itemStacks/IItemStack.cs index 5ba7d17..74c5fc2 100644 --- a/scripts/item/itemStacks/IItemStack.cs +++ b/scripts/item/itemStacks/IItemStack.cs @@ -78,8 +78,8 @@ public interface IItemStack /// 判断能从指定物品堆中接收的物品数量 /// /// - /// 向该物品堆中放入物品的物品堆 /// Item stack to add to the current stack + /// 向该物品堆中放入物品的物品堆 /// /// public int CanTakeFrom(IItemStack itemStack); diff --git a/scripts/item/itemStacks/PacksackStack.cs b/scripts/item/itemStacks/PacksackStack.cs new file mode 100644 index 0000000..b3ff671 --- /dev/null +++ b/scripts/item/itemStacks/PacksackStack.cs @@ -0,0 +1,63 @@ +using System; + +using Godot; + +namespace ColdMint.scripts.item.itemStacks; + + +/// +/// ItemStack for item. Can add items into pack by stack them to this stack. +/// 用于物品的堆栈。可以将物品堆叠到此堆栈中,从而将物品添加到背包中。 +/// +/// +public class PacksackStack(Packsack packsack) : IItemStack +{ + public int MaxQuantity => 1; + public int Quantity => 1; + public bool Empty { get; private set; } + public Texture2D Icon => packsack.Icon; + public string Name => packsack.Name; + public string? Description => packsack.Description; + + public bool CanAddItem(IItem item) => packsack.ItemContainer?.CanAddItem(item) ?? false; + + public bool AddItem(IItem item) => packsack.ItemContainer?.AddItem(item) ?? false; + + public int CanTakeFrom(IItemStack itemStack) => packsack.ItemContainer?.CanAddItemStack(itemStack) ?? 0; + + public bool TakeFrom(IItemStack itemStack) => packsack.ItemContainer?.AddItemStack(itemStack) ?? false; + + public IItem? GetItem() + { + return Empty ? packsack : null; + } + + public IItem? PickItem() + { + if (Empty) return null; + Empty = true; + return packsack; + } + + public IItemStack? PickItems(int value) + { + if (Empty || value == 0) return null; + Empty = true; + return new PacksackStack(packsack); + } + + public int RemoveItem(int number) + { + if (Empty || number == 0) return number; + Empty = true; + packsack.Destroy(); + return Math.Max(0, number - 1); + } + + public void ClearStack() + { + if (Empty) return; + packsack.Destroy(); + Empty = true; + } +} \ No newline at end of file From 0f9e7d028333b5c635a51e0e2329b913f53eb4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Fri, 14 Jun 2024 12:44:31 +0800 Subject: [PATCH 2/3] =?UTF-8?q?Change=20the=20index=20parameter=20when=20a?= =?UTF-8?q?dding=20a=20slot=20to=20ItemContainer=20to=20automatically=20ge?= =?UTF-8?q?t=20the=20latest=20index=20,=20add=20a=20test=20slot=20for=20Pa?= =?UTF-8?q?cksack=20item=20=E6=9B=B4=E6=94=B9ItemContainer=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=A7=BD=E4=BD=8D=E6=97=B6=E7=9A=84index=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=B8=BA=E8=87=AA=E5=8A=A8=E8=8E=B7=E5=8F=96=E6=9C=80?= =?UTF-8?q?=E6=96=B0=E7=B4=A2=E5=BC=95=EF=BC=8C=E4=B8=BAPacksack=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E4=B8=80=E4=B8=AA=E6=B5=8B=E8=AF=95=E7=94=A8=E6=A7=BD?= =?UTF-8?q?=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/inventory/HotBar.cs | 2 +- scripts/inventory/IItemContainer.cs | 3 +-- scripts/inventory/UniversalItemContainer.cs | 6 +++--- scripts/item/Packsack.cs | 3 +++ 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/inventory/HotBar.cs b/scripts/inventory/HotBar.cs index 0cc99dd..84e7a27 100644 --- a/scripts/inventory/HotBar.cs +++ b/scripts/inventory/HotBar.cs @@ -20,7 +20,7 @@ public partial class HotBar : HBoxContainer NodeUtils.DeleteAllChild(this); for (var i = 0; i < Config.HotBarSize; i++) { - _itemContainer.AddItemSlot(this, i); + _itemContainer.AddItemSlot(this); } } diff --git a/scripts/inventory/IItemContainer.cs b/scripts/inventory/IItemContainer.cs index 72ee577..1a5a36b 100644 --- a/scripts/inventory/IItemContainer.cs +++ b/scripts/inventory/IItemContainer.cs @@ -219,8 +219,7 @@ public interface IItemContainer : IEnumerable /// 添加物品槽 /// /// - /// - void AddItemSlot(Node rootNode, int index); + void AddItemSlot(Node rootNode); /// /// SelectTheNextItemSlot diff --git a/scripts/inventory/UniversalItemContainer.cs b/scripts/inventory/UniversalItemContainer.cs index 938f094..5d47e56 100644 --- a/scripts/inventory/UniversalItemContainer.cs +++ b/scripts/inventory/UniversalItemContainer.cs @@ -22,7 +22,7 @@ public class UniversalItemContainer : IItemContainer { private readonly PackedScene? _itemSlotPackedScene = GD.Load("res://prefab/ui/ItemSlot.tscn"); - private readonly List? _itemSlotNodes = new(); + private readonly List? _itemSlotNodes = []; /// /// Character @@ -221,7 +221,7 @@ public class UniversalItemContainer : IItemContainer /// Add items tank /// 添加物品槽 /// - public void AddItemSlot(Node rootNode, int index) + public void AddItemSlot(Node rootNode) { if (_itemSlotNodes == null || _itemSlotPackedScene == null) { @@ -234,7 +234,7 @@ public class UniversalItemContainer : IItemContainer return; } - itemSlotNode.IsSelect = index == _selectIndex; + itemSlotNode.IsSelect = (_itemSlotNodes.Count ) == _selectIndex; _itemSlotNodes.Add(itemSlotNode); } diff --git a/scripts/item/Packsack.cs b/scripts/item/Packsack.cs index 6a9aa16..6ac8e91 100644 --- a/scripts/item/Packsack.cs +++ b/scripts/item/Packsack.cs @@ -49,5 +49,8 @@ public partial class Packsack : RigidBody2D, IItem { base._Ready(); ItemContainer = new UniversalItemContainer(); + + //Test: Add one ItemSlot for pack + ItemContainer.AddItemSlot(this); } } \ No newline at end of file From bb44d77805b2d7dd03dcc7276e8a32ed3500eb46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=A7=E9=9B=A8=E7=83=A8?= Date: Fri, 14 Jun 2024 19:12:06 +0800 Subject: [PATCH 3/3] =?UTF-8?q?Ban=20Packsack=20nesting=20=E7=A6=81?= =?UTF-8?q?=E6=AD=A2=E8=83=8C=E5=8C=85=E5=B5=8C=E5=A5=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/item/itemStacks/PacksackStack.cs | 26 +++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/scripts/item/itemStacks/PacksackStack.cs b/scripts/item/itemStacks/PacksackStack.cs index b3ff671..a70a22e 100644 --- a/scripts/item/itemStacks/PacksackStack.cs +++ b/scripts/item/itemStacks/PacksackStack.cs @@ -4,7 +4,6 @@ using Godot; namespace ColdMint.scripts.item.itemStacks; - /// /// ItemStack for item. Can add items into pack by stack them to this stack. /// 用于物品的堆栈。可以将物品堆叠到此堆栈中,从而将物品添加到背包中。 @@ -19,13 +18,30 @@ public class PacksackStack(Packsack packsack) : IItemStack public string Name => packsack.Name; public string? Description => packsack.Description; - public bool CanAddItem(IItem item) => packsack.ItemContainer?.CanAddItem(item) ?? false; + //todo: 只拒绝是背包的物品是权宜之计,应该为物品加入一个“是否可以放入背包”的属性来实现这个判断。 + public bool CanAddItem(IItem item) + { + if (item is Packsack) return false; + return packsack.ItemContainer?.CanAddItem(item) ?? false; + } - public bool AddItem(IItem item) => packsack.ItemContainer?.AddItem(item) ?? false; + public bool AddItem(IItem item) + { + if (item is Packsack) return false; + return packsack.ItemContainer?.AddItem(item) ?? false; + } - public int CanTakeFrom(IItemStack itemStack) => packsack.ItemContainer?.CanAddItemStack(itemStack) ?? 0; + public int CanTakeFrom(IItemStack itemStack) + { + if (itemStack.GetItem() is Packsack) return 0; + return packsack.ItemContainer?.CanAddItemStack(itemStack) ?? 0; + } - public bool TakeFrom(IItemStack itemStack) => packsack.ItemContainer?.AddItemStack(itemStack) ?? false; + public bool TakeFrom(IItemStack itemStack) + { + if (itemStack.GetItem() is Packsack) return false; + return packsack.ItemContainer?.AddItemStack(itemStack) ?? false; + } public IItem? GetItem() {