using System.Collections.Generic; using ColdMint.scripts.utils; using Godot; namespace ColdMint.scripts.inventory; /// /// HotBar /// 快捷物品栏 /// public partial class HotBar : HBoxContainer, IItemContainer { private PackedScene? _itemSlotPackedScene; private List? _itemSlotNodes; /// /// UnknownIndex /// 未知位置 /// private const int UnknownIndex = -1; //_selectIndex默认为0. private int _selectIndex; public override void _Ready() { base._Ready(); NodeUtils.DeleteAllChild(this); _itemSlotNodes = new List(); _itemSlotPackedScene = GD.Load("res://prefab/ui/ItemSlot.tscn"); for (var i = 0; i < Config.HotBarSize; i++) { AddItemSlot(i); } } /// /// Select the next item slot /// 选择下一个物品槽 /// private void SelectTheNextItemSlot() { if (_itemSlotNodes == null) { return; } var count = _itemSlotNodes.Count; if (count == 0) { return; } var oldSelectIndex = _selectIndex; _selectIndex++; if (_selectIndex >= count) { _selectIndex = 0; } SelectItemSlot(oldSelectIndex, _selectIndex); } /// /// Select the previous item slot /// 选择上一个物品槽 /// private void SelectThePreviousItemSlot() { if (_itemSlotNodes == null) { return; } var count = _itemSlotNodes.Count; if (count == 0) { return; } var oldSelectIndex = _selectIndex; _selectIndex--; if (_selectIndex < 0) { _selectIndex = count - 1; } SelectItemSlot(oldSelectIndex, _selectIndex); } public override void _Process(double delta) { base._Process(delta); if (Input.IsActionJustPressed("hotbar_next")) { //Mouse wheel down //鼠标滚轮向下 SelectTheNextItemSlot(); } if (Input.IsActionJustPressed("hotbar_previous")) { //Mouse wheel up //鼠标滚轮向上 SelectThePreviousItemSlot(); } if (Input.IsActionJustPressed("hotbar_1")) { SelectItemSlotByHotBarShortcutKey(0); } if (Input.IsActionJustPressed("hotbar_2")) { SelectItemSlotByHotBarShortcutKey(1); } if (Input.IsActionJustPressed("hotbar_3")) { SelectItemSlotByHotBarShortcutKey(2); } if (Input.IsActionJustPressed("hotbar_4")) { SelectItemSlotByHotBarShortcutKey(3); } if (Input.IsActionJustPressed("hotbar_5")) { SelectItemSlotByHotBarShortcutKey(4); } if (Input.IsActionJustPressed("hotbar_6")) { SelectItemSlotByHotBarShortcutKey(5); } if (Input.IsActionJustPressed("hotbar_7")) { SelectItemSlotByHotBarShortcutKey(6); } if (Input.IsActionJustPressed("hotbar_8")) { SelectItemSlotByHotBarShortcutKey(7); } if (Input.IsActionJustPressed("hotbar_9")) { SelectItemSlotByHotBarShortcutKey(8); } } /// /// Select the HotBar project using the shortcut keys /// 通过快捷键选择HotBar项目 /// /// The Pc version of the shortcut key index is 0-9 /// Pc版本的快捷键索引为0-9 /// private void SelectItemSlotByHotBarShortcutKey(int shortcutKeyIndex) { if (_itemSlotNodes == null) { return; } var safeIndex = GetSafeIndex(shortcutKeyIndex); if (safeIndex == UnknownIndex) { return; } SelectItemSlot(_selectIndex, safeIndex); _selectIndex = safeIndex; } /// /// Removes an item from the currently selected inventory /// 移除当前选中的物品栏内的物品 /// /// /// public bool RemoveItemFromItemSlotBySelectIndex(int number) { return RemoveItemFromItemSlot(_selectIndex, number); } public int GetItemSlotCount() { if (_itemSlotNodes == null) { return 0; } return _itemSlotNodes.Count; } public ItemSlotNode? GetItemSlotNode(int index) { if (_itemSlotNodes == null) { return null; } var safeIndex = GetSafeIndex(index); return _itemSlotNodes[safeIndex]; } /// /// Remove items from the item slot /// 从物品槽内移除物品 /// /// ///When this number is greater than the number of item slots, residual filtering is used. ///当此数量大于物品槽的数量时,会使用余数筛选。 /// /// ///The number of items removed ///移除物品的数量 /// public bool RemoveItemFromItemSlot(int itemSlotIndex, int number) { if (_itemSlotNodes == null) { return false; } var safeIndex = GetSafeIndex(itemSlotIndex); if (safeIndex == UnknownIndex) { return false; } var itemSlot = _itemSlotNodes[safeIndex]; return itemSlot.RemoveItem(number); } /// /// Gets a secure subscript index /// 获取安全的下标索引 /// /// /// ///-1 is returned on failure, and the index that does not result in an out-of-bounds subscript is returned on success ///失败返回-1,成功返回不会导致下标越界的索引 /// private int GetSafeIndex(int itemSlotIndex) { if (_itemSlotNodes == null) { return UnknownIndex; } var count = _itemSlotNodes.Count; if (count == 0) { //Prevents the dividend from being 0 //防止被除数为0 return UnknownIndex; } return itemSlotIndex % count; } /// /// Select an item slot /// 选中某个物品槽 /// private void SelectItemSlot(int oldSelectIndex, int newSelectIndex) { if (oldSelectIndex == newSelectIndex) { return; } if (_itemSlotNodes == null) { return; } _itemSlotNodes[oldSelectIndex].IsSelect = false; _itemSlotNodes[newSelectIndex].IsSelect = true; var oldItem = _itemSlotNodes[oldSelectIndex].GetItem(); if (oldItem != null && oldItem is Node2D oldNode2D) { oldNode2D.ProcessMode = ProcessModeEnum.Disabled; oldNode2D.Hide(); } var item = _itemSlotNodes[newSelectIndex].GetItem(); if (item == null) { if (GameSceneNodeHolder.Player != null) { GameSceneNodeHolder.Player.CurrentItem = null; } } else { if (item is Node2D node2D) { node2D.ProcessMode = ProcessModeEnum.Inherit; node2D.Show(); if (GameSceneNodeHolder.Player != null) { GameSceneNodeHolder.Player.CurrentItem = node2D; } } else { if (GameSceneNodeHolder.Player != null) { GameSceneNodeHolder.Player.CurrentItem = null; } } } } public bool CanAddItem(IItem item) { return Matching(item) != null; } /// /// Add an item to the HotBar /// 在HotBar内添加一个物品 /// /// /// public bool AddItem(IItem item) { var itemSlotNode = Matching(item); if (itemSlotNode == null) { return false; } return itemSlotNode.SetItem(item); } public int GetSelectIndex() { return _selectIndex; } public ItemSlotNode? GetSelectItemSlotNode() { if (_itemSlotNodes == null || _itemSlotNodes.Count == 0) { return null; } if (_selectIndex < _itemSlotNodes.Count) { //Prevent subscripts from going out of bounds. //防止下标越界。 return _itemSlotNodes[_selectIndex]; } return null; } public ItemSlotNode? Matching(IItem item) { if (_itemSlotNodes == null || _itemSlotNodes.Count == 0) { return null; } foreach (var itemSlotNode in _itemSlotNodes) { if (itemSlotNode.CanSetItem(item)) { //If there is an item slot to put this item in, then we return it. //如果有物品槽可放置此物品,那么我们返回它。 return itemSlotNode; } } return null; } /// /// Add items tank /// 添加物品槽 /// private void AddItemSlot(int index) { if (_itemSlotNodes == null || _itemSlotPackedScene == null) { return; } var itemSlotNode = _itemSlotPackedScene.Instantiate() as ItemSlotNode; if (itemSlotNode == null) { return; } AddChild(itemSlotNode); itemSlotNode.IsSelect = index == _selectIndex; _itemSlotNodes.Add(itemSlotNode); } }