diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs
index 8494134..4422ab2 100644
--- a/scripts/character/CharacterTemplate.cs
+++ b/scripts/character/CharacterTemplate.cs
@@ -41,14 +41,7 @@ public partial class CharacterTemplate : CharacterBody2D
//Item containers are used to store items.
//物品容器用于存储物品。
- private IItemContainer? _itemContainer;
-
-
- public IItemContainer? ItemContainer
- {
- get => _itemContainer;
- set => _itemContainer = value;
- }
+ public IItemContainer? ItemContainer { get; set; }
//Items currently held
//当前持有的物品
@@ -282,14 +275,14 @@ public partial class CharacterTemplate : CharacterBody2D
return false;
}
- if (_itemContainer == null)
+ if (ItemContainer == null)
{
return false;
}
//Get the currently selected node
//拿到当前选择的节点
- var itemSlotNode = _itemContainer.GetSelectItemSlotNode();
+ var itemSlotNode = ItemContainer.GetSelectItemSlotNode();
if (itemSlotNode == null)
{
return false;
@@ -297,7 +290,7 @@ public partial class CharacterTemplate : CharacterBody2D
//First check if we can pick up the item.
//先检查我们能否拾起此物品。
- var canPick = _itemContainer.CanAddItem(item);
+ var canPick = ItemContainer.CanAddItem(item);
if (!canPick)
{
return false;
@@ -305,7 +298,7 @@ public partial class CharacterTemplate : CharacterBody2D
//Is it successfully added to the container?
//再检查是否成功的添加到容器内了?
- var addSuccess = _itemContainer.AddItem(item);
+ var addSuccess = ItemContainer.AddItem(item);
if (!addSuccess)
{
return false;
@@ -504,7 +497,7 @@ public partial class CharacterTemplate : CharacterBody2D
///
protected virtual void EnterThePickingRangeBody(Node node)
{
- if (node is not IItem)
+ if (node is not IItem_New item)
{
return;
}
@@ -519,7 +512,7 @@ public partial class CharacterTemplate : CharacterBody2D
///
protected virtual void ExitThePickingRangeBody(Node node)
{
- if (node is not IItem)
+ if (node is not IItem_New)
{
return;
}
@@ -549,12 +542,12 @@ public partial class CharacterTemplate : CharacterBody2D
{
//If the item container is null, then return
//如果物品容器为null,那么返回
- if (_itemContainer == null)
+ if (ItemContainer == null)
{
return;
}
- var len = _itemContainer.GetItemSlotCount();
+ var len = ItemContainer.GetItemSlotCount();
if (len == 0)
{
return;
@@ -599,7 +592,7 @@ public partial class CharacterTemplate : CharacterBody2D
///
protected void ThrowItem(int index, int number, Vector2 velocity)
{
- var itemSlotNode = _itemContainer?.GetItemSlotNode(index);
+ var itemSlotNode = ItemContainer?.GetItemSlotNode(index);
var item = itemSlotNode?.GetItem();
diff --git a/scripts/inventory/HotBar.cs b/scripts/inventory/HotBar.cs
index 4fb129a..f9dda26 100644
--- a/scripts/inventory/HotBar.cs
+++ b/scripts/inventory/HotBar.cs
@@ -339,7 +339,7 @@ public partial class HotBar : HBoxContainer, IItemContainer
{
return false;
}
- return itemSlotNode.SetItem(item);
+ return itemSlotNode.ReplaceItemStack(item);
}
public int GetSelectIndex()
@@ -374,7 +374,7 @@ public partial class HotBar : HBoxContainer, IItemContainer
foreach (var itemSlotNode in _itemSlotNodes)
{
- if (itemSlotNode.CanSetItem(item))
+ if (itemSlotNode.CanAddItem(item))
{
//If there is an item slot to put this item in, then we return it.
//如果有物品槽可放置此物品,那么我们返回它。
diff --git a/scripts/inventory/ItemSlotNode.cs b/scripts/inventory/ItemSlotNode.cs
index 93a07f5..ea526a6 100644
--- a/scripts/inventory/ItemSlotNode.cs
+++ b/scripts/inventory/ItemSlotNode.cs
@@ -42,7 +42,49 @@ public partial class ItemSlotNode : MarginContainer
/// 获取物品槽内的物品堆
///
///
- public IItemStack GetItemStack() => _itemStack;
+ public IItemStack? GetItemStack() => _itemStack;
+
+ ///
+ /// If present, get the item at the top of the item stack in this slot
+ /// 如果存在,获取该槽位中物品堆顶部的物品
+ ///
+ public IItem_New? GetItem() => _itemStack?.GetItem();
+
+ ///
+ /// If present, remove an item in this slot and return it.
+ /// 如果存在,移除该槽位中的一个物品并将其返回
+ ///
+ ///
+ public IItem_New? PickItem()
+ {
+ if (_itemStack is null) return null;
+
+ var result = _itemStack.PickItem();
+ if (_itemStack.Quantity == 0) ClearSlot();
+ else UpdateAllDisplay();
+
+ return result;
+ }
+
+ ///
+ /// Remove the specified number of items and return them as a new item stack
+ /// 取出当前物品槽中指定数量的物品,并作为新的物品堆返回
+ ///
+ ///
+ /// Quantity to be taken out, inputs below zero represent all items
+ /// 要取出的数量,小于0的输入代表全部物品
+ ///
+ ///
+ public IItemStack? PickItems(int value)
+ {
+ if (_itemStack is null) return null;
+
+ var result = _itemStack.PickItems(value);
+ if (_itemStack.Quantity == 0) ClearSlot();
+ else UpdateAllDisplay();
+
+ return result;
+ }
///
/// Removes the specified number of items from the item slot
@@ -53,6 +95,9 @@ public partial class ItemSlotNode : MarginContainer
/// The remaining number, if the number of items in the current item stack is less than the specified number. Otherwise,0
/// 若物品槽内物品少于指定的数量,返回相差的数量。否则返回0
///
+ ///
+ /// 会将移除的物品从游戏中删除,如果目的并非如此,请考虑使用
+ ///
public int RemoveItem(int number)
{
if (_itemStack == null)
@@ -64,133 +109,139 @@ public partial class ItemSlotNode : MarginContainer
//If the specified number of items is removed, the number of items is less than or equal to 0. Then we empty the inventory.
//如果移除指定数量的物品后,物品数量小于或等于0。那么我们清空物品栏。
if (_itemStack.Quantity == 0) ClearSlot();
- else
- {
- UpdateTooltipText(_itemStack);
- UpdateQuantityLabel(_itemStack.Quantity);
- }
+ else UpdateAllDisplay();
return result;
-
- // var newNumber = _item.Quantity - number;
- // if (newNumber <= 0)
- // {
- // //If the specified number of items is removed, the number of items is less than or equal to 0. Then we return the removal successful and empty the inventory.
- // //如果移除指定数量的物品后,物品数量小于或等于0。那么我们返回移除成功,并清空物品栏。
- // ClearItem();
- // return true;
- // }
- // else
- // {
- // _item.Quantity = newNumber;
- // UpdateTooltipText(_item);
- // UpdateQuantityLabel(_item.Quantity);
- // return true;
- // }
}
+ ///
+ /// Remove item stack from slot and return it, equivalent to ReplaceItemStack(null)
+ /// 从当前槽位中移出并返回物品堆,等价于ReplaceItemStack(null)
+ ///
+ ///
+ public IItemStack? RemoveItemStack() => ReplaceItemStack(null);
+
///
/// Empty the item slot
- /// 清空物品槽
+ /// 清空当前物品槽
///
///
- ///This method does not calculate how many items should be left. If you want to remove a specified number of items, call the method.
- ///此方法不会计算物品应该剩余多少个。若您希望移除指定数量的物品,请调用方法。
+ ///This method will remove all items stored in the item slots from the game, if this is not what you want to do, consider using the method.
+ ///此方法会从游戏中移除储存于物品槽中的所有物品,若这不是您希望的操作,请考虑使用方法。
///
public void ClearSlot()
{
+ _itemStack?.ClearStack();
_itemStack = null;
-
- if (_iconTextureRect != null)
- {
- _iconTextureRect.Texture = null;
- }
- if (_control != null)
- {
- _control.TooltipText = null;
- }
-
- _quantityLabel?.Hide();
+ UpdateAllDisplay();
}
- //Todo: I searched until here.
-
///
/// Can the specified item be placed in the item slot?
/// 指定的物品是否可设置在物品槽内?
///
///
///
- public bool CanSetItem(IItem item)
+ public bool CanAddItem(IItem_New item)
{
- if (_item == null)
- {
- return true;
- }
-
- //This inventory already has items, but the items in this inventory are not the same as the incoming items
- //这个物品栏已经有物品了,但是这个物品栏的物品和传入的物品不一样
- if (_item.Id != item.Id)
- {
- return false;
- }
-
- var newQuantity = _item.Quantity + item.Quantity;
- if (newQuantity > item.MaxStackQuantity)
- {
- //If the amount of the current item exceeds the maximum stack amount after placing it in this inventory
- //如果将当前物品放置到这个物品栏后,数量超过了最大叠加数量
- return false;
- }
-
- return true;
+ if (_itemStack == null) return true;
+ return _itemStack.CanAddItem(item);
}
///
- /// Sets items for the item slot
- /// 为物品槽设置物品
+ ///
+ /// Set item stack for this slot, this will completely replace current item stack.
+ /// If you want the item stack to be added to current stack, use the .
+ ///
+ /// 为物品槽设置物品堆,将完全替换掉当前物品堆。如果想要物品堆叠加至该物品堆,请使用
///
- ///
- ///
- public bool SetItem(IItem item)
+ ///
+ /// The item stack that was previously in this slot
+ /// 该槽位中原本的物品堆
+ ///
+ public IItemStack? ReplaceItemStack(IItemStack? newItemStack)
{
- if (!CanSetItem(item))
- {
- return false;
- }
+ var result = _itemStack;
+ _itemStack = newItemStack;
- if (_item == null)
- {
- if (item.Icon != null && _iconTextureRect != null)
- {
- _iconTextureRect.Texture = item.Icon;
- }
+ UpdateAllDisplay();
- _item = item;
- UpdateTooltipText(item);
- UpdateQuantityLabel(item.Quantity);
- return true;
+ return result;
+ }
+
+ ///
+ /// Try to add an item to this slot, if it can't be added to this slot, return false
+ /// 尝试向当前槽位中加入物品,如果该物品不能被放入该槽位,返回false
+ ///
+ public bool AddItem(IItem_New item)
+ {
+ bool result;
+ if (_itemStack is null)
+ {
+ _itemStack = IItemStack.FromItem(item);
+ result = true;
}
else
{
- var newQuantity = _item.Quantity + item.Quantity;
- _item.Quantity = newQuantity;
- UpdateTooltipText(item);
- UpdateQuantityLabel(newQuantity);
- return true;
+ result = _itemStack.AddItem(item);
}
+
+ if (result)
+ {
+ UpdateAllDisplay();
+ }
+
+ return result;
+ }
+
+ ///
+ /// Try to combine an item stack into this slot
+ /// 尝试将一个物品堆合并至该槽位中
+ ///
+ ///
+ /// Number of items remaining in the source item pile after the operation is completed
+ /// 操作完成后,源物品堆中剩余的物品数
+ ///
+ public int AddItemStack(IItemStack itemStack)
+ {
+ int result;
+ if (_itemStack is null)
+ {
+ _itemStack = itemStack;
+ result = 0;
+ }
+ else
+ {
+ result = _itemStack.TakeFrom(itemStack);
+ }
+
+ UpdateAllDisplay();
+ return result;
+ }
+
+
+ ///
+ /// Update all displays of this slot
+ /// 更新该槽位的一切显示信息
+ ///
+ private void UpdateAllDisplay()
+ {
+ UpdateIconTexture();
+ UpdateQuantityLabel();
+ UpdateTooltipText();
}
///
/// Update item tips
/// 更新物品的提示内容
///
- ///
- private void UpdateTooltipText(IItem item)
+ private void UpdateTooltipText()
{
- if (_control == null)
+ if (_control == null) return;
+ if (_itemStack == null)
{
+ _control.TooltipText = null;
return;
}
@@ -199,16 +250,16 @@ public partial class ItemSlotNode : MarginContainer
var debugText = TranslationServerUtils.Translate("item_prompt_debug");
if (debugText != null)
{
- _control.TooltipText = string.Format(debugText, item.Id,
- TranslationServerUtils.Translate(item.Name),
- item.Quantity, item.MaxStackQuantity, item.GetType().Name,
- TranslationServerUtils.Translate(item.Description));
+ _control.TooltipText = string.Format(debugText, _itemStack.Id,
+ TranslationServerUtils.Translate(_itemStack.Name),
+ _itemStack.Quantity, _itemStack.MaxQuantity, _itemStack.GetType().Name,
+ TranslationServerUtils.Translate(_itemStack.Description));
}
}
else
{
- _control.TooltipText = TranslationServerUtils.Translate(item.Name) + "\n" +
- TranslationServerUtils.Translate(item.Description);
+ _control.TooltipText = TranslationServerUtils.Translate(_itemStack.Name) + "\n" +
+ TranslationServerUtils.Translate(_itemStack.Description);
}
}
@@ -216,28 +267,36 @@ public partial class ItemSlotNode : MarginContainer
/// Update quantity label
/// 更新数量标签
///
- ///
- private void UpdateQuantityLabel(int? quantity)
+ private void UpdateQuantityLabel()
{
if (_quantityLabel == null)
{
return;
}
- switch (quantity)
+ switch (_itemStack?.Quantity)
{
- case null:
+ case null or 1:
_quantityLabel.Hide();
return;
- case > 1:
- //When the quantity is greater than 1, we display the quantity.
- //当数量大于1时,我们显示数量
- _quantityLabel.Text = quantity.ToString();
+ default:
+ //When the quantity is not null or 1, we display the quantity.
+ //当数量不为null或1时,我们显示数量
+ _quantityLabel.Text = _itemStack?.Quantity.ToString();
_quantityLabel.Show();
break;
- default:
- _quantityLabel.Hide();
- break;
+ }
+ }
+
+ ///
+ /// Update texture of the icon rect
+ /// 更新显示的物品图标
+ ///
+ private void UpdateIconTexture()
+ {
+ if (_iconTextureRect != null)
+ {
+ _iconTextureRect.Texture = _itemStack?.Icon;
}
}
diff --git a/scripts/item/IItemStack.cs b/scripts/item/IItemStack.cs
index 1ff6bd9..1ebfba7 100644
--- a/scripts/item/IItemStack.cs
+++ b/scripts/item/IItemStack.cs
@@ -4,6 +4,9 @@ using Godot;
namespace ColdMint.scripts.item;
+///
+/// Item stack in an inventory slot
+///
public interface IItemStack
{
///
@@ -36,10 +39,81 @@ public interface IItemStack
///
string? Description { get; }
+ ///
+ /// Determine whether a specified item can be accommodated
+ /// 判断能否容纳指定物品
+ ///
+ ///
+ public bool CanAddItem(IItem_New item);
///
- /// Removes the specified number of items from current item stack
- /// 在当前物品堆移除指定数量的物品
+ /// Hold a given item
+ ///
+ /// Item to hold by current stack
+ /// Whether successful
+ public bool AddItem(IItem_New item);
+
+ ///
+ /// 判断能从指定物品堆中接收的物品数量
+ ///
+ ///
+ /// 向该物品堆中放入物品的物品堆
+ /// Item stack to add to the current stack
+ ///
+ ///
+ public int CanTakeFrom(IItemStack itemStack);
+
+ ///
+ /// 将指定物品堆中尽可能多的物品移动至当前物品堆中,被移入当前堆的物品应从原物品堆中移除。
+ ///
+ ///
+ /// 被移入当前堆的物品堆
+ ///
+ ///
+ /// 操作结束后原物品堆中剩余的物品数
+ ///
+ public int TakeFrom(IItemStack itemStack);
+
+ ///
+ /// Get item instance at the top of current stack without removing it from stack
+ /// 获取当前物品堆顶部的物品实例而不取出该物品
+ ///
+ ///
+ ///
+ public IItem_New? GetItem();
+
+ ///
+ /// Pop the item instance at the top of current item stack and return it
+ /// 取出当前物品堆顶部的物品实例并返回该物品
+ ///
+ ///
+ ///
+ public IItem_New? PickItem();
+
+ ///
+ /// Remove the specified number of items and return them as a new item stack
+ /// 取出当前堆中指定数量的物品,并作为新的物品堆返回
+ ///
+ ///
+ ///
+ /// Quantity to be taken out, inputs below zero represent all items
+ /// 要取出的数量,小于0的输入代表全部物品
+ ///
+ ///
+ /// The item stack that is taken out, can be null if out nothing, should not be the current item stack itself
+ /// 取出的物品堆,没有取出物品时可为null,不应是当前物品堆自身
+ ///
+ public IItemStack? PickItems(int value);
+
+ ///
+ ///
+ /// Removes the specified number of items from current item stack,removed items should be removed from the game
+ /// If you don't want remove them from game, consider and
+ ///
+ ///
+ /// 在当前物品堆移除指定数量的物品,被移除的物品应当从游戏中移除。
+ /// 如果您不想将它们从游戏中移除,请考虑: 、
+ ///
///
///
///
@@ -48,6 +122,11 @@ public interface IItemStack
///
public int RemoveItem(int number);
+ ///
+ /// Clear current stack, which means should dispose all items inside current stack here
+ ///
+ public void ClearStack();
+
///
/// Create a new ItemStack with the given item as the first item
///
diff --git a/scripts/item/IItem_New.cs b/scripts/item/IItem_New.cs
index d98e25d..a046842 100644
--- a/scripts/item/IItem_New.cs
+++ b/scripts/item/IItem_New.cs
@@ -28,4 +28,9 @@ public interface IItem_New
/// Owner of current item, if any
/// Target position, such as the position of the cursor when used by the player
void Use(Node2D? owner, Vector2 targetGlobalPosition);
+
+ ///
+ /// Execute when current item be removed from game.
+ ///
+ void Destroy();
}
\ No newline at end of file
diff --git a/scripts/item/SingleItemStack.cs b/scripts/item/SingleItemStack.cs
index b853990..d7c3415 100644
--- a/scripts/item/SingleItemStack.cs
+++ b/scripts/item/SingleItemStack.cs
@@ -1,21 +1,41 @@
-using ColdMint.scripts.inventory;
+using System;
+
+using ColdMint.scripts.inventory;
using Godot;
namespace ColdMint.scripts.item;
///
-/// Item stack in inventory
+/// Item stack of single item
///
//maybe we'd move this into inventory namespace
-public readonly struct SingleItemStack(IItem_New item) : IItemStack
+public struct SingleItemStack(IItem_New item) : IItemStack
{
public IItem_New Item { get; init; } = item;
public string Id => Item.Id;
public int MaxQuantity => 1;
- public int Quantity => 1;
+ public int Quantity { get; set; } = 1;
public Texture2D Icon => Item.Icon;
public string Name => Item.Name;
public string? Description => Item.Description;
+
+ public bool CanAddItem(IItem_New item) => false;
+
+ public bool AddItem(IItem_New item) => false;
+
+ public int CanTakeFrom(IItemStack itemStack) => 0;
+
+ public int TakeFrom(IItemStack itemStack) => 0;
+
+ public int RemoveItem(int number)
+ {
+
+ }
+
+ public void ClearStack()
+ {
+ throw new System.NotImplementedException();
+ }
}
\ No newline at end of file