Add whether the item is selected.Adjust the display logic of the backpack UI.

加入物品是否被选择。调整背包UI的显示逻辑。
This commit is contained in:
Cold-Mint 2024-06-19 22:33:00 +08:00
parent a58ddeb039
commit 1e5b466c6f
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
10 changed files with 140 additions and 42 deletions

View File

@ -6,10 +6,10 @@ uid="uid://cc0k86apkvut7"
[deps] [deps]
files=["res://locals/Slogan.zh.translation", "res://locals/Slogan.en.translation", "res://locals/Slogan.ja.translation"] files=["res://locals/slogan.zh.translation", "res://locals/slogan.en.translation", "res://locals/slogan.ja.translation"]
source_file="res://locals/Slogan.csv" source_file="res://locals/slogan.csv"
dest_files=["res://locals/Slogan.zh.translation", "res://locals/Slogan.en.translation", "res://locals/Slogan.ja.translation"] dest_files=["res://locals/slogan.zh.translation", "res://locals/slogan.en.translation", "res://locals/slogan.ja.translation"]
[params] [params]

View File

@ -1,6 +1,9 @@
using ColdMint.scripts.character; using ColdMint.scripts.character;
using ColdMint.scripts.inventory; using ColdMint.scripts.inventory;
using ColdMint.scripts.item;
using ColdMint.scripts.loader.uiLoader;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.events;
using ColdMint.scripts.utils;
using Godot; using Godot;
namespace ColdMint.scripts; namespace ColdMint.scripts;
@ -85,4 +88,36 @@ public static class GameSceneNodeHolder
///<para>背包Ui容器内存放的是背包ui节点的容器。当用户使用背包时会从背包ui容器内将其背包对于的节点展示出来。</para> ///<para>背包Ui容器内存放的是背包ui节点的容器。当用户使用背包时会从背包ui容器内将其背包对于的节点展示出来。</para>
/// </remarks> /// </remarks>
public static Control? BackpackUiContainer { get; set; } public static Control? BackpackUiContainer { get; set; }
/// <summary>
/// <para>Hide the knapsack node in the knapsack Ui if the knapsack UI is displayed</para>
/// <para>如果背包Ui处于显示状态那么隐藏背包UI内的背包节点</para>
/// </summary>
public static void HideBackpackUiContainerIfVisible()
{
if (BackpackUiContainer == null)
{
return;
}
if (!BackpackUiContainer.Visible)
{
return;
}
NodeUtils.ForEachNode<PacksackUi>(BackpackUiContainer, node =>
{
//If the child node is not visible, the traversal continues.
//如果子节点不可见,则继续遍历。
if (!node.Visible)
return false;
//Until you find a visible node, hide it, and return true, ending the loop.
//直到找到可见的节点隐藏该节点然后返回true结束遍历。
node.Hide();
return true;
});
}
} }

View File

@ -264,6 +264,7 @@ public partial class Player : CharacterTemplate
} }
ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity()); ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity());
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
CurrentItem = null; CurrentItem = null;
} }
} }

View File

@ -45,6 +45,7 @@ public partial class HotBar : HBoxContainer
{ {
//Mouse wheel down //Mouse wheel down
//鼠标滚轮向下 //鼠标滚轮向下
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
_itemContainer?.SelectTheNextItemSlot(); _itemContainer?.SelectTheNextItemSlot();
} }
@ -52,6 +53,7 @@ public partial class HotBar : HBoxContainer
{ {
//Mouse wheel up //Mouse wheel up
//鼠标滚轮向上 //鼠标滚轮向上
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
_itemContainer?.SelectThePreviousItemSlot(); _itemContainer?.SelectThePreviousItemSlot();
} }
@ -110,11 +112,11 @@ public partial class HotBar : HBoxContainer
/// <param name="shortcutKeyIndex"></param> /// <param name="shortcutKeyIndex"></param>
private void SelectItemSlotByHotBarShortcutKey(int shortcutKeyIndex) private void SelectItemSlotByHotBarShortcutKey(int shortcutKeyIndex)
{ {
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
if (_itemContainer == null) if (_itemContainer == null)
{ {
return; return;
} }
_itemContainer.SelectItemSlot(shortcutKeyIndex); _itemContainer.SelectItemSlot(shortcutKeyIndex);
} }

View File

@ -32,6 +32,12 @@ public interface IItemContainer : IEnumerable<ItemSlotNode>
/// <returns></returns> /// <returns></returns>
bool AddItem(IItem item); bool AddItem(IItem item);
/// <summary>
/// <para>Whether this item container supports checking</para>
/// <para>此物品容器是否支持选中</para>
/// </summary>
public bool SupportSelect { get; set; }
/// <summary> /// <summary>
/// <para>Determines the number of items that can be received from the specified pile</para> /// <para>Determines the number of items that can be received from the specified pile</para>
/// <para>判断能从指定物品堆中接收的物品数量</para> /// <para>判断能从指定物品堆中接收的物品数量</para>

View File

@ -1,7 +1,5 @@
using System;
using ColdMint.scripts.item; using ColdMint.scripts.item;
using ColdMint.scripts.item.itemStacks; using ColdMint.scripts.item.itemStacks;
using ColdMint.scripts.map.events;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
@ -21,7 +19,6 @@ public partial class ItemSlotNode : MarginContainer
private bool _isSelect; private bool _isSelect;
private Texture2D? _backgroundTexture; private Texture2D? _backgroundTexture;
private Texture2D? _backgroundTextureWhenSelect; private Texture2D? _backgroundTextureWhenSelect;
public Action<ItemStackChangeEvent>? ItemStackChangeEvent;
public override void _Ready() public override void _Ready()
{ {
@ -37,7 +34,7 @@ public partial class ItemSlotNode : MarginContainer
public override Variant _GetDragData(Vector2 atPosition) public override Variant _GetDragData(Vector2 atPosition)
{ {
if (_iconTextureRect == null || _itemStack == null) if (_isSelect || _iconTextureRect == null || _itemStack == null)
{ {
//Drag is not allowed if there is no icon or no pile of items. //Drag is not allowed if there is no icon or no pile of items.
//如果没有图标或者没有物品堆,那么不允许拖动。 //如果没有图标或者没有物品堆,那么不允许拖动。
@ -78,7 +75,6 @@ public partial class ItemSlotNode : MarginContainer
return false; return false;
} }
//TODOThis is where we infer whether the two piles can merge.在这里推断两个物品堆是否可以融合。
return _itemStack == null; return _itemStack == null;
} }
@ -105,6 +101,7 @@ public partial class ItemSlotNode : MarginContainer
//尝试获取源物品堆时返回null。 //尝试获取源物品堆时返回null。
return; return;
} }
ReplaceItemStack(itemStack); ReplaceItemStack(itemStack);
} }
@ -411,11 +408,6 @@ public partial class ItemSlotNode : MarginContainer
private void SetItemStack(IItemStack? itemStack) private void SetItemStack(IItemStack? itemStack)
{ {
_itemStack = itemStack; _itemStack = itemStack;
var stackChangeEvent = new ItemStackChangeEvent
{
ItemStack = itemStack
};
ItemStackChangeEvent?.Invoke(stackChangeEvent);
} }
/// <summary> /// <summary>
@ -429,6 +421,4 @@ public partial class ItemSlotNode : MarginContainer
_iconTextureRect.Texture = _itemStack?.Icon; _iconTextureRect.Texture = _itemStack?.Icon;
} }
} }
} }

View File

@ -36,6 +36,9 @@ public class UniversalItemContainer : IItemContainer
//_selectIndex默认为0. //_selectIndex默认为0.
private int _selectIndex; private int _selectIndex;
public bool SupportSelect { get; set; } = true;
public bool CanAddItem(IItem item) public bool CanAddItem(IItem item)
{ {
return Match(item) != null; return Match(item) != null;
@ -78,12 +81,17 @@ public class UniversalItemContainer : IItemContainer
public int GetSelectIndex() public int GetSelectIndex()
{ {
if (!SupportSelect)
{
return 0;
}
return _selectIndex; return _selectIndex;
} }
public ItemSlotNode? GetSelectItemSlotNode() public ItemSlotNode? GetSelectItemSlotNode()
{ {
if (_itemSlotNodes == null || _itemSlotNodes.Count == 0) if (!SupportSelect || _itemSlotNodes == null || _itemSlotNodes.Count == 0)
{ {
return null; return null;
} }
@ -98,11 +106,35 @@ public class UniversalItemContainer : IItemContainer
return null; return null;
} }
public IItem? PickItemFromItemSlotBySelectIndex() => PickItemFromItemSlot(_selectIndex); public IItem? PickItemFromItemSlotBySelectIndex()
{
if (!SupportSelect)
{
return null;
}
public IItemStack? PickItemsFromItemSlotBySelectIndex(int value) => PickItemsFromItemSlot(_selectIndex, value); return PickItemFromItemSlot(_selectIndex);
}
public int RemoveItemFromItemSlotBySelectIndex(int number) => RemoveItemFromItemSlot(_selectIndex, number); public IItemStack? PickItemsFromItemSlotBySelectIndex(int value)
{
if (!SupportSelect)
{
return null;
}
return PickItemsFromItemSlot(_selectIndex, value);
}
public int RemoveItemFromItemSlotBySelectIndex(int number)
{
if (!SupportSelect)
{
return 0;
}
return RemoveItemFromItemSlot(_selectIndex, number);
}
public int GetItemSlotCount() public int GetItemSlotCount()
{ {
@ -232,7 +264,15 @@ public class UniversalItemContainer : IItemContainer
return null; return null;
} }
if (SupportSelect)
{
itemSlotNode.IsSelect = (_itemSlotNodes.Count) == _selectIndex; itemSlotNode.IsSelect = (_itemSlotNodes.Count) == _selectIndex;
}
else
{
itemSlotNode.IsSelect = false;
}
_itemSlotNodes.Add(itemSlotNode); _itemSlotNodes.Add(itemSlotNode);
// itemSlotNode.ItemStackChangeEvent += @event => // itemSlotNode.ItemStackChangeEvent += @event =>
// { // {
@ -265,7 +305,7 @@ public class UniversalItemContainer : IItemContainer
public void SelectTheNextItemSlot() public void SelectTheNextItemSlot()
{ {
if (_itemSlotNodes == null) if (!SupportSelect || _itemSlotNodes == null)
{ {
return; return;
} }
@ -288,7 +328,7 @@ public class UniversalItemContainer : IItemContainer
public void SelectThePreviousItemSlot() public void SelectThePreviousItemSlot()
{ {
if (_itemSlotNodes == null) if (!SupportSelect || _itemSlotNodes == null)
{ {
return; return;
} }
@ -311,7 +351,7 @@ public class UniversalItemContainer : IItemContainer
public void SelectItemSlot(int newSelectIndex) public void SelectItemSlot(int newSelectIndex)
{ {
if (newSelectIndex == _selectIndex) if (!SupportSelect || newSelectIndex == _selectIndex)
{ {
return; return;
} }
@ -331,6 +371,11 @@ public class UniversalItemContainer : IItemContainer
/// </summary> /// </summary>
private void PrivateSelectItemSlot(int oldSelectIndex, int newSelectIndex) private void PrivateSelectItemSlot(int oldSelectIndex, int newSelectIndex)
{ {
if (!SupportSelect)
{
return;
}
if (oldSelectIndex == newSelectIndex) if (oldSelectIndex == newSelectIndex)
{ {
return; return;

View File

@ -57,6 +57,7 @@ public partial class Packsack : PickAbleTemplate
{ {
base._Ready(); base._Ready();
ItemContainer = new UniversalItemContainer(); ItemContainer = new UniversalItemContainer();
ItemContainer.SupportSelect = false;
//When the backpack is created, the item slot is generated. //When the backpack is created, the item slot is generated.
//当背包被创建时,物品槽就被生成出来了。 //当背包被创建时,物品槽就被生成出来了。
for (var i = 0; i < NumberSlots; i++) for (var i = 0; i < NumberSlots; i++)

View File

@ -1,16 +0,0 @@
using ColdMint.scripts.item.itemStacks;
namespace ColdMint.scripts.map.events;
/// <summary>
/// <para>ItemStackChangeEvent</para>
/// <para>物品堆改变事件</para>
/// </summary>
public class ItemStackChangeEvent
{
/// <summary>
/// <para>Changed ItemStack</para>
/// <para>改变后的物品堆</para>
/// </summary>
public IItemStack? ItemStack { get; set; }
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.item; using ColdMint.scripts.item;
@ -36,6 +37,39 @@ public static class NodeUtils
return deleteNumber; return deleteNumber;
} }
/// <summary>
/// <para>Traverse the child nodes of type T under the parent node</para>
/// <para>遍历父节点下T类型的子节点</para>
/// </summary>
/// <param name="parent"></param>
/// <param name="func">
///<para>A function that handles callbacks and returns true to terminate the traversal of the node</para>
///<para>用于处理回调的函数返回true终止遍历节点</para>
/// </param>
/// <typeparam name="T">
///<para>When the type is specified as Node, all child nodes are returned.</para>
///<para>当指定类型为Node时将返回所有子节点。</para>
/// </typeparam>
public static void ForEachNode<T>(Node parent, Func<T,bool> func) where T : Node
{
var count = parent.GetChildCount();
if (count <= 0)
{
return;
}
for (var i = 0; i < count; i++)
{
var node = parent.GetChild(i);
if (node is not T t) continue;
if (func.Invoke(t))
{
break;
}
}
}
/// <summary> /// <summary>
/// <para>All child nodes are removed asynchronously</para> /// <para>All child nodes are removed asynchronously</para>
/// <para>异步删除所有子节点</para> /// <para>异步删除所有子节点</para>