Adds the selected slot change event to the item container.

加入物品容器选中的槽位改变事件。
This commit is contained in:
Cold-Mint 2024-06-20 00:02:32 +08:00
parent 1e5b466c6f
commit 5d6d42aa54
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
8 changed files with 143 additions and 129 deletions

View File

@ -37,3 +37,4 @@ log_found_item_types,从文件中找到{0}个物品类型,Found {0} item types i
log_register_item,注册物品类型{0}结果为{1},Registered item type {0}; results in {1},登録されたアイテム・タイプ {0} の結果は {1} です。
log_error_when_open_item_regs_dir,尝试打开物品信息目录时发生错误,Error when opening itemRegs dir,アイテム情報カタログを開こうとしてエラーが発生しました。
log_wrong_custom_arg,不匹配的参数:类型为{0}而值为{1},Mismatched parameter: type {0} and value {1},パラメータの不一致:型{0}と値{1}。
log_item_container_is_null,物品容器为空,Item container is null,アイテム・コンテナが空です
1 id zh en ja
37 log_item_container_is_null 物品容器为空 Item container is null アイテム・コンテナが空です
38
39
40

View File

@ -7,7 +7,6 @@ using ColdMint.scripts.debug;
using ColdMint.scripts.health;
using ColdMint.scripts.inventory;
using ColdMint.scripts.item;
using ColdMint.scripts.item.itemStacks;
using ColdMint.scripts.utils;
using ColdMint.scripts.item.weapon;
using ColdMint.scripts.loot;
@ -40,9 +39,20 @@ public partial class CharacterTemplate : CharacterBody2D
protected string? CharacterName;
protected IItemContainer? ProtectedItemContainer;
//Item containers are used to store items.
//物品容器用于存储物品。
public IItemContainer? ItemContainer { get; set; }
public IItemContainer? ItemContainer
{
get => ProtectedItemContainer;
set
{
ProtectedItemContainer = value;
WhenBindItemContainer(ProtectedItemContainer);
}
}
//Items currently held
//当前持有的物品
@ -58,6 +68,16 @@ public partial class CharacterTemplate : CharacterBody2D
}
}
/// <summary>
/// <para>When binding an item container to a character</para>
/// <para>当为角色绑定物品容器时</para>
/// </summary>
/// <param name="itemContainer"></param>
protected virtual void WhenBindItemContainer(IItemContainer? itemContainer)
{
}
/// <summary>
/// <para>When the items the character holds are updated</para>
/// <para>当角色持有的物品更新时</para>
@ -618,7 +638,6 @@ public partial class CharacterTemplate : CharacterBody2D
{
var itemSlotNode = ItemContainer?.GetItemSlotNode(index);
if (itemSlotNode is null) return;
if (number < 0)
{
while (!itemSlotNode.IsEmpty())

View File

@ -1,9 +1,9 @@
using System;
using System.Text;
using System.Threading.Tasks;
using ColdMint.scripts.damage;
using ColdMint.scripts.deathInfo;
using ColdMint.scripts.inventory;
using ColdMint.scripts.item;
using ColdMint.scripts.map.events;
using ColdMint.scripts.utils;
@ -62,6 +62,43 @@ public partial class Player : CharacterTemplate
}
}
protected override void WhenBindItemContainer(IItemContainer? itemContainer)
{
if (itemContainer == null)
{
return;
}
//Subscribe to events when the item container is bound to the player.
//在物品容器与玩家绑定时订阅事件。
itemContainer.SelectedItemSlotChangeEvent += SelectedItemSlotChangeEvent;
}
public override void _ExitTree()
{
base._ExitTree();
if (ProtectedItemContainer != null)
{
//Unsubscribe to events when this object is destroyed.
//此节点被销毁时,取消订阅事件。
ProtectedItemContainer.SelectedItemSlotChangeEvent -= SelectedItemSlotChangeEvent;
}
}
private void SelectedItemSlotChangeEvent(SelectedItemSlotChangeEvent selectedItemSlotChangeEvent)
{
var item = selectedItemSlotChangeEvent.NewItemSlotNode?.GetItemStack()?.GetItem();
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
if (item is Node2D node2D)
{
CurrentItem = node2D;
}
else
{
CurrentItem = null;
}
}
/// <summary>
/// <para>Update operation prompt</para>
/// <para>更新操作提示</para>
@ -103,7 +140,7 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_down")[0].AsText()));
TranslationServerUtils.Translate(InputMap.ActionGetEvents("ui_down")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("action_jump_down"));
}
@ -117,7 +154,7 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText()));
TranslationServerUtils.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("action_pick_up"));
operationTipLabel.Text = operationTipBuilder.ToString();
@ -140,7 +177,7 @@ public partial class Player : CharacterTemplate
operationTipBuilder.Append(Config.OperationTipActionColor);
operationTipBuilder.Append(']');
operationTipBuilder.Append(
TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText()));
TranslationServerUtils.Translate(InputMap.ActionGetEvents("use_item")[0].AsText()));
operationTipBuilder.Append("[/color]");
operationTipBuilder.Append(TranslationServerUtils.Translate("action_use_item"));
operationTipBuilder.Append(TranslationServerUtils.Translate(item.Name));
@ -244,8 +281,8 @@ public partial class Player : CharacterTemplate
}
_parabola.Points = CurrentItem == null
? _emptyVector2Array
: ParabolicUtils.ComputeParabolic(ItemMarker2D.Position, GetThrowVelocity(), Gravity, 0.1f);
? _emptyVector2Array
: ParabolicUtils.ComputeParabolic(ItemMarker2D.Position, GetThrowVelocity(), Gravity, 0.1f);
}
@ -404,8 +441,8 @@ public partial class Player : CharacterTemplate
var rotationDegreesNode2D = node2D.RotationDegrees;
var rotationDegreesNode2DAbs = Math.Abs(rotationDegreesNode2D);
_floatLabel.Position = rotationDegreesNode2DAbs > 90
? new Vector2(0, PromptTextDistance)
: new Vector2(0, -PromptTextDistance);
? new Vector2(0, PromptTextDistance)
: new Vector2(0, -PromptTextDistance);
_floatLabel.RotationDegrees = 0 - rotationDegreesNode2D;
var label = _floatLabel.GetNode<Label>("Label");
if (node is PickAbleTemplate pickAbleTemplate)

View File

@ -1,3 +1,4 @@
using System;
using ColdMint.scripts.map.events;
using ColdMint.scripts.utils;
using Godot;
@ -12,11 +13,13 @@ public partial class HotBar : HBoxContainer
{
private IItemContainer? _itemContainer;
Action<SelectedItemSlotChangeEvent>? SelectedItemSlotChangeEvent { get; set; }
public override void _Ready()
{
base._Ready();
_itemContainer = new UniversalItemContainer();
EventManager.PlayerInstanceChangeEvent += PlayerInstanceChangeEvent;
_itemContainer.SelectedItemSlotChangeEvent += SelectedItemSlotChangeEvent;
NodeUtils.DeleteAllChild(this);
for (var i = 0; i < Config.HotBarSize; i++)
{
@ -25,19 +28,6 @@ public partial class HotBar : HBoxContainer
}
/// <summary>
/// <para>When the player instance changes, we update the binding of the item container</para>
/// <para>当玩家实例改变时,我们更新物品容器的绑定</para>
/// </summary>
/// <param name="playerInstanceChangeEvent"></param>
private void PlayerInstanceChangeEvent(PlayerInstanceChangeEvent playerInstanceChangeEvent)
{
if (_itemContainer is UniversalItemContainer universalItemContainer)
{
universalItemContainer.CharacterTemplate = GameSceneNodeHolder.Player;
}
}
public override void _Process(double delta)
{
base._Process(delta);
@ -45,7 +35,6 @@ public partial class HotBar : HBoxContainer
{
//Mouse wheel down
//鼠标滚轮向下
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
_itemContainer?.SelectTheNextItemSlot();
}
@ -53,7 +42,6 @@ public partial class HotBar : HBoxContainer
{
//Mouse wheel up
//鼠标滚轮向上
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
_itemContainer?.SelectThePreviousItemSlot();
}
@ -112,11 +100,11 @@ public partial class HotBar : HBoxContainer
/// <param name="shortcutKeyIndex"></param>
private void SelectItemSlotByHotBarShortcutKey(int shortcutKeyIndex)
{
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
if (_itemContainer == null)
{
return;
}
_itemContainer.SelectItemSlot(shortcutKeyIndex);
}
@ -128,6 +116,9 @@ public partial class HotBar : HBoxContainer
public override void _ExitTree()
{
base._ExitTree();
EventManager.PlayerInstanceChangeEvent -= PlayerInstanceChangeEvent;
if (_itemContainer != null)
{
_itemContainer.SelectedItemSlotChangeEvent -= SelectedItemSlotChangeEvent;
}
}
}

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using ColdMint.scripts.item;
using ColdMint.scripts.item.itemStacks;
using ColdMint.scripts.map.events;
using Godot;
namespace ColdMint.scripts.inventory;
@ -16,6 +17,12 @@ namespace ColdMint.scripts.inventory;
/// </remarks>
public interface IItemContainer : IEnumerable<ItemSlotNode>
{
/// <summary>
/// <para>This event is triggered when the selected item slot changes</para>
/// <para>当选中的物品槽改变时,触发此事件</para>
/// </summary>
Action<SelectedItemSlotChangeEvent>? SelectedItemSlotChangeEvent { get; set; }
/// <summary>
/// <para>Can the specified item be added to the container?</para>
/// <para>指定的物品是否可添加到容器内?</para>

View File

@ -2,9 +2,9 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ColdMint.scripts.character;
using ColdMint.scripts.item;
using ColdMint.scripts.item.itemStacks;
using ColdMint.scripts.map.events;
using ColdMint.scripts.utils;
using Godot;
using JetBrains.Annotations;
@ -21,11 +21,6 @@ public class UniversalItemContainer : IItemContainer
private readonly List<ItemSlotNode>? _itemSlotNodes = [];
/// <summary>
/// <para>Character</para>
/// <para>角色</para>
/// </summary>
public CharacterTemplate? CharacterTemplate { get; set; }
/// <summary>
/// <para>UnknownIndex</para>
@ -39,6 +34,8 @@ public class UniversalItemContainer : IItemContainer
public bool SupportSelect { get; set; } = true;
public Action<SelectedItemSlotChangeEvent>? SelectedItemSlotChangeEvent { get; set; }
public bool CanAddItem(IItem item)
{
return Match(item) != null;
@ -274,32 +271,6 @@ public class UniversalItemContainer : IItemContainer
}
_itemSlotNodes.Add(itemSlotNode);
// itemSlotNode.ItemStackChangeEvent += @event =>
// {
// if (_itemSlotNodes == null)
// {
// return;
// }
//
// var index = _itemSlotNodes.IndexOf(itemSlotNode);
// // LogCat.Log("位于" + index + "的堆改变了。" + _selectIndex + "空的吗" + (@event.ItemStack == null));
// if (index == -1)
// {
// return;
// }
//
// if (index == _selectIndex)
// {
// if (@event.ItemStack == null)
// {
// HideItem(index);
// }
// else
// {
// DisplayItem(index);
// }
// }
// };
return itemSlotNode;
}
@ -371,25 +342,22 @@ public class UniversalItemContainer : IItemContainer
/// </summary>
private void PrivateSelectItemSlot(int oldSelectIndex, int newSelectIndex)
{
if (!SupportSelect)
if (!SupportSelect || _itemSlotNodes == null || oldSelectIndex == newSelectIndex)
{
return;
}
if (oldSelectIndex == newSelectIndex)
{
return;
}
if (_itemSlotNodes == null)
{
return;
}
_itemSlotNodes[oldSelectIndex].IsSelect = false;
_itemSlotNodes[newSelectIndex].IsSelect = true;
var oldItemSlotNode = _itemSlotNodes[oldSelectIndex];
oldItemSlotNode.IsSelect = false;
var newItemSlotNode = _itemSlotNodes[newSelectIndex];
newItemSlotNode.IsSelect = true;
HideItem(oldSelectIndex);
DisplayItem(newSelectIndex);
SelectedItemSlotChangeEvent?.Invoke(new SelectedItemSlotChangeEvent
{
NewItemSlotNode = newItemSlotNode,
OldItemSlotNode = oldItemSlotNode
});
_selectIndex = newSelectIndex;
}
@ -400,17 +368,10 @@ public class UniversalItemContainer : IItemContainer
/// <param name="index"></param>
private void HideItem(int index)
{
if (_itemSlotNodes == null)
{
return;
}
var oldItem = _itemSlotNodes[index].GetItemStack()?.GetItem();
if (oldItem is Node2D oldNode2D)
{
oldNode2D.ProcessMode = Node.ProcessModeEnum.Disabled;
oldNode2D.Hide();
}
var oldItem = _itemSlotNodes?[index].GetItemStack()?.GetItem();
if (oldItem is not Node2D oldNode2D) return;
oldNode2D.ProcessMode = Node.ProcessModeEnum.Disabled;
oldNode2D.Hide();
}
/// <summary>
@ -424,44 +385,10 @@ public class UniversalItemContainer : IItemContainer
/// <param name="index"></param>
private void DisplayItem(int index)
{
if (_itemSlotNodes == null)
{
return;
}
var item = _itemSlotNodes[index].GetItemStack()?.GetItem();
switch (item)
{
case null:
{
if (CharacterTemplate != null)
{
CharacterTemplate.CurrentItem = null;
}
break;
}
case Node2D node2D:
{
node2D.ProcessMode = Node.ProcessModeEnum.Inherit;
node2D.Show();
if (CharacterTemplate != null)
{
CharacterTemplate.CurrentItem = node2D;
}
break;
}
default:
{
if (CharacterTemplate != null)
{
CharacterTemplate.CurrentItem = null;
}
break;
}
}
var item = _itemSlotNodes?[index].GetItemStack()?.GetItem();
if (item is not Node2D newNode2D) return;
newNode2D.ProcessMode = Node.ProcessModeEnum.Inherit;
newNode2D.Show();
}

View File

@ -1,4 +1,5 @@
using ColdMint.scripts.character;
using System;
using ColdMint.scripts.character;
using ColdMint.scripts.debug;
using ColdMint.scripts.map.events;
using ColdMint.scripts.utils;
@ -58,7 +59,16 @@ public partial class PlayerSpawn : Marker2D
{
return;
}
playerNode.ItemContainer = GameSceneNodeHolder.HotBar?.GetItemContainer();
var itemContainer = GameSceneNodeHolder.HotBar?.GetItemContainer();
if (itemContainer == null)
{
//Throws an exception when the item container is empty.
//当物品容器为空时,抛出异常。
throw new NullReferenceException(TranslationServerUtils.Translate("log_item_container_is_null"));
}
playerNode.ItemContainer = itemContainer;
GameSceneNodeHolder.Player = playerNode;
playerNode.Position = GlobalPosition;
LogCat.LogWithFormat("player_spawn_debug", playerNode.ReadOnlyCharacterName, playerNode.Position);

View File

@ -0,0 +1,22 @@
using ColdMint.scripts.inventory;
namespace ColdMint.scripts.map.events;
/// <summary>
/// <para>Selected item slot changes event</para>
/// <para>选中的物品槽改变事件</para>
/// </summary>
public class SelectedItemSlotChangeEvent
{
/// <summary>
/// <para></para>
/// <para>新选中的物品槽</para>
/// </summary>
public ItemSlotNode? NewItemSlotNode { get; set; }
/// <summary>
/// <para>Lost the selected item slot</para>
/// <para>失去选中的物品槽</para>
/// </summary>
public ItemSlotNode? OldItemSlotNode { get; set; }
}