Merge branch 'master' of github.com:Cold-Mint/Traveller
This commit is contained in:
commit
30a0a6539f
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,17 @@ public interface IItemContainer : IEnumerable<ItemSlotNode>
|
|||
/// <returns></returns>
|
||||
bool AddItem(IItem item);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Determines the number of items that can be received from the specified pile</para>
|
||||
/// <para>判断能从指定物品堆中接收的物品数量</para>
|
||||
/// </summary>
|
||||
/// <param name="itemStack">
|
||||
/// <para>Item stack to add to the current container</para>
|
||||
/// <para>向该容器中放入物品的物品堆</para>
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
int CanAddItemStack(IItemStack itemStack);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Add an stack of items to this container</para>
|
||||
/// <para>向当前容器中存入一堆物品</para>
|
||||
|
@ -179,8 +190,8 @@ public interface IItemContainer : IEnumerable<ItemSlotNode>
|
|||
ItemSlotNode? Match(IItemStack stack);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Match the first item slot that has item stack that satisfies the predicate</para>
|
||||
/// <para>匹配首个拥有满足指定条件的物品堆的物品槽</para>
|
||||
/// <para>Match the first item slot that satisfies the predicate</para>
|
||||
/// <para>匹配首个拥有满足指定条件的物品槽</para>
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns>
|
||||
|
@ -188,11 +199,11 @@ public interface IItemContainer : IEnumerable<ItemSlotNode>
|
|||
/// <para>若没有满足条件的槽位,返回null</para>
|
||||
/// </returns>
|
||||
/// <seealso cref="MatchAll"/>
|
||||
ItemSlotNode? Match(Func<IItemStack?, bool> predicate);
|
||||
ItemSlotNode? Match(Func<ItemSlotNode, bool> predicate);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Match all item slots that has item stack that satisfies the predicate</para>
|
||||
/// <para>匹配所有拥有满足指定条件的物品堆的物品槽</para>
|
||||
/// <para>Match all item slots that satisfies the predicate</para>
|
||||
/// <para>匹配所有拥有满足指定条件的物品槽</para>
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns>
|
||||
|
@ -200,7 +211,7 @@ public interface IItemContainer : IEnumerable<ItemSlotNode>
|
|||
/// <para>包含匹配到的槽位的IEnumerable,当没有满足条件的槽位时为空</para>
|
||||
/// </returns>
|
||||
/// <seealso cref="Match(Func{IItemStack?,bool})"/>
|
||||
IEnumerable<ItemSlotNode> MatchAll(Func<IItemStack?, bool> predicate);
|
||||
IEnumerable<ItemSlotNode> MatchAll(Func<ItemSlotNode, bool> predicate);
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -208,8 +219,7 @@ public interface IItemContainer : IEnumerable<ItemSlotNode>
|
|||
/// <para>添加物品槽</para>
|
||||
/// </summary>
|
||||
/// <param name="rootNode"></param>
|
||||
/// <param name="index"></param>
|
||||
void AddItemSlot(Node rootNode, int index);
|
||||
void AddItemSlot(Node rootNode);
|
||||
|
||||
/// <summary>
|
||||
/// <para>SelectTheNextItemSlot</para>
|
||||
|
|
|
@ -143,18 +143,6 @@ public partial class ItemSlotNode : MarginContainer
|
|||
UpdateAllDisplay();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Can the specified item be placed in the item slot?</para>
|
||||
/// <para>指定的物品是否可设置在物品槽内?</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool CanAddItem(IItem item)
|
||||
{
|
||||
if (_itemStack == null) return true;
|
||||
return _itemStack.CanAddItem(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Set item stack for this slot, this will completely replace current item stack.
|
||||
|
@ -176,6 +164,18 @@ public partial class ItemSlotNode : MarginContainer
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Can the specified item be placed in the item slot?</para>
|
||||
/// <para>指定的物品是否可设置在物品槽内?</para>
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool CanAddItem(IItem item)
|
||||
{
|
||||
if (_itemStack == null) return true;
|
||||
return _itemStack.CanAddItem(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Try to add an item to this slot, if it can't be added to this slot, return false</para>
|
||||
/// <para>尝试向当前槽位中加入物品,如果该物品不能被放入该槽位,返回false</para>
|
||||
|
@ -201,6 +201,21 @@ public partial class ItemSlotNode : MarginContainer
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Determines the number of items that can be received from the specified pile</para>
|
||||
/// <para>判断能从指定物品堆中接收的物品数量</para>
|
||||
/// </summary>
|
||||
/// <param name="itemStack">
|
||||
/// <para>Item stack to add to the current slot</para>
|
||||
/// <para>向该物品槽中放入物品的物品堆</para>
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public int CanAddItemStack(IItemStack itemStack)
|
||||
{
|
||||
if (_itemStack is null) return itemStack.Quantity;
|
||||
return _itemStack.CanTakeFrom(itemStack);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Try to combine an item stack into this slot</para>
|
||||
/// <para>尝试将一个物品堆合并至该槽位中</para>
|
||||
|
|
|
@ -22,7 +22,7 @@ public class UniversalItemContainer : IItemContainer
|
|||
{
|
||||
private readonly PackedScene? _itemSlotPackedScene = GD.Load<PackedScene>("res://prefab/ui/ItemSlot.tscn");
|
||||
|
||||
private readonly List<ItemSlotNode>? _itemSlotNodes = new();
|
||||
private readonly List<ItemSlotNode>? _itemSlotNodes = [];
|
||||
|
||||
/// <summary>
|
||||
/// <para>Character</para>
|
||||
|
@ -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<IItemStack?, bool> predicate)
|
||||
public ItemSlotNode? Match(Func<ItemSlotNode, bool> predicate)
|
||||
{
|
||||
return _itemSlotNodes?.FirstOrDefault(node => predicate(node.GetItemStack()));
|
||||
return _itemSlotNodes?.FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
public IEnumerable<ItemSlotNode> MatchAll(Func<IItemStack?, bool> predicate)
|
||||
public IEnumerable<ItemSlotNode> MatchAll(Func<ItemSlotNode, bool> predicate)
|
||||
{
|
||||
return from node in _itemSlotNodes where predicate(node.GetItemStack()) select node;
|
||||
return from node in _itemSlotNodes where predicate(node) select node;
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,7 +221,7 @@ public class UniversalItemContainer : IItemContainer
|
|||
/// <para>Add items tank</para>
|
||||
/// <para>添加物品槽</para>
|
||||
/// </summary>
|
||||
public void AddItemSlot(Node rootNode, int index)
|
||||
public void AddItemSlot(Node rootNode)
|
||||
{
|
||||
if (_itemSlotNodes == null || _itemSlotPackedScene == null)
|
||||
{
|
||||
|
@ -224,7 +234,7 @@ public class UniversalItemContainer : IItemContainer
|
|||
return;
|
||||
}
|
||||
|
||||
itemSlotNode.IsSelect = index == _selectIndex;
|
||||
itemSlotNode.IsSelect = (_itemSlotNodes.Count ) == _selectIndex;
|
||||
_itemSlotNodes.Add(itemSlotNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,20 @@ 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();
|
||||
}
|
||||
ItemContainer = new UniversalItemContainer();
|
||||
|
||||
public IItemContainer? GetItemContainer()
|
||||
{
|
||||
return _itemContainer;
|
||||
//Test: Add one ItemSlot for pack
|
||||
ItemContainer.AddItemSlot(this);
|
||||
}
|
||||
}
|
|
@ -78,8 +78,8 @@ public interface IItemStack
|
|||
/// <para>判断能从指定物品堆中接收的物品数量</para>
|
||||
/// </summary>
|
||||
/// <param name="itemStack">
|
||||
/// <para>向该物品堆中放入物品的物品堆</para>
|
||||
/// <para>Item stack to add to the current stack</para>
|
||||
/// <para>向该物品堆中放入物品的物品堆</para>
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public int CanTakeFrom(IItemStack itemStack);
|
||||
|
|
79
scripts/item/itemStacks/PacksackStack.cs
Normal file
79
scripts/item/itemStacks/PacksackStack.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
|
||||
using Godot;
|
||||
|
||||
namespace ColdMint.scripts.item.itemStacks;
|
||||
|
||||
/// <summary>
|
||||
/// <para>ItemStack for <see cref="Packsack"/> item. Can add items into pack by stack them to this stack.</para>
|
||||
/// <para>用于<see cref="Packsack"/>物品的堆栈。可以将物品堆叠到此堆栈中,从而将物品添加到背包中。</para>
|
||||
/// </summary>
|
||||
/// <param name="packsack"></param>
|
||||
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;
|
||||
|
||||
//todo: 只拒绝是背包的物品是权宜之计,应该为物品加入一个“是否可以放入背包”的属性来实现这个判断。
|
||||
public bool CanAddItem(IItem item)
|
||||
{
|
||||
if (item is Packsack) return false;
|
||||
return packsack.ItemContainer?.CanAddItem(item) ?? false;
|
||||
}
|
||||
|
||||
public bool AddItem(IItem item)
|
||||
{
|
||||
if (item is Packsack) return false;
|
||||
return packsack.ItemContainer?.AddItem(item) ?? false;
|
||||
}
|
||||
|
||||
public int CanTakeFrom(IItemStack itemStack)
|
||||
{
|
||||
if (itemStack.GetItem() is Packsack) return 0;
|
||||
return packsack.ItemContainer?.CanAddItemStack(itemStack) ?? 0;
|
||||
}
|
||||
|
||||
public bool TakeFrom(IItemStack itemStack)
|
||||
{
|
||||
if (itemStack.GetItem() is Packsack) return false;
|
||||
return 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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user