From 7365434f2b3e9d85e9f54eaa1f6e4b570f79937d Mon Sep 17 00:00:00 2001 From: Cold-Mint Date: Thu, 11 Jul 2024 23:06:47 +0800 Subject: [PATCH] =?UTF-8?q?Fixed=20an=20issue=20where=20players=20could=20?= =?UTF-8?q?pick=20up=20items=20that=20had=20already=20been=20picked=20up?= =?UTF-8?q?=20by=20other=20creatures.=20Reuse=20floating=20label=20instanc?= =?UTF-8?q?es.=20=E4=BF=AE=E5=A4=8D=E7=8E=A9=E5=AE=B6=E8=83=BD=E5=A4=9F?= =?UTF-8?q?=E6=8D=A1=E8=B5=B7=E5=B7=B2=E8=A2=AB=E5=85=B6=E4=BB=96=E7=94=9F?= =?UTF-8?q?=E7=89=A9=E6=8D=A1=E8=B5=B7=E7=9A=84=E7=89=A9=E5=93=81=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82=E5=A4=8D=E7=94=A8=E6=82=AC=E6=B5=AE?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E5=AE=9E=E4=BE=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locals/Log.csv | 5 +- scripts/character/CharacterTemplate.cs | 68 ++++++++++------ scripts/character/Player.cs | 106 +++++++++++++++---------- scripts/utils/NodeUtils.cs | 18 ++--- 4 files changed, 123 insertions(+), 74 deletions(-) diff --git a/locals/Log.csv b/locals/Log.csv index a23ea4d..7186f21 100644 --- a/locals/Log.csv +++ b/locals/Log.csv @@ -72,4 +72,7 @@ log_state_processor_not_found,找不到状态处理器{0}。,State processor {0} log_chase_no_enemy,追逐没有敌人。,Chase no enemy.,敵がいない追跡です。 log_bubble_not_found,找不到气泡{0}。,Bubble {0} not found.,バブル{0}が見つかりません。 log_owner_is_not_AiCharacter,所有者不是AiCharacter。,Owner is not AiCharacter.,所有者はAiCharacterではありません。 -log_weaponContainer_is_null,武器容器为空。,Weapon container is null.,武器コンテナが空です。 \ No newline at end of file +log_weaponContainer_is_null,武器容器为空。,Weapon container is null.,武器コンテナが空です。 +log_find_nearest_item,查找最近的物品。,Find the nearest item.,最も近いアイテムを見つけます。 +log_float_label_instantiate_failed,浮动标签实例化失败。,Float label instantiation failed.,フロートラベルのインスタンス化に失敗しました。 +log_pickable_picked_up,可拾捡物被捡起了,那么不显示标签。,"If the pickable item is picked up, the label is not displayed.",でも、拾得物が拾い上げられたら、ラベルは表示されません。 \ No newline at end of file diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index cb7417f..0a540dd 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -218,20 +218,14 @@ public partial class CharacterTemplate : CharacterBody2D /// public Node2D? FindTheNearestItem() { + LogCat.Log("find_nearest_item"); if (PickingRangeBodiesList == null || PickingRangeBodiesList.Count == 0) { return null; } - HashSet? exclude = null; - if (_currentItem != null) - { - //Prevent picking up objects in your hands again. - //防止再次捡起自己手上的物品。 - exclude = new HashSet { _currentItem }; - } - - return NodeUtils.GetTheNearestNode(this, PickingRangeBodiesList.ToArray(), exclude); + return NodeUtils.GetTheNearestNode(this, PickingRangeBodiesList.ToArray(), true, + node => !CanPickItem(node)); } @@ -308,25 +302,53 @@ public partial class CharacterTemplate : CharacterBody2D } } + /// + /// Whether you can pick up specified items + /// 是否能捡起指定物品 + /// + /// + /// + private bool CanPickItem(Node node) + { + if (_currentItem != null && node == _currentItem) + { + //Do not include your own belongings. + //不包含自己手上的物品。 + return false; + } + + if (node is PickAbleTemplate pickAbleTemplate) + { + //Does not contain items that have been picked up. + //不包含已被捡起的物品。 + return !pickAbleTemplate.Picked; + } + + return false; + } + /// /// Pick up the specified items /// 将指定物品拾起来 /// - /// + /// /// ///Whether successfully picked up ///是否成功拾起 /// - public bool PickItem(Node2D? pickAbleItem) + protected bool PickItem(Node2D? pickAbleItemNode2D) { //Empty reference checking is implicitly performed here. //此处隐式的执行了空引用检查。 - if (pickAbleItem is not IItem item) + if (pickAbleItemNode2D is not IItem item) { return false; } - if (ItemContainer == null) + + //The item store is marked null, or the item container is null. + //物品存放的标记为null,或者物品容器为null。 + if (ItemMarker2D == null || ItemContainer == null) { return false; } @@ -339,10 +361,10 @@ public partial class CharacterTemplate : CharacterBody2D return false; } - //First check if we can pick up the item. - //先检查我们能否拾起此物品。 - var canPick = ItemContainer.CanAddItem(item); - if (!canPick) + //Check to see if you can fit the item into the container first. + //先检查是否能将物品放入容器。 + var canAddItem = ItemContainer.CanAddItem(item); + if (!canAddItem) { return false; } @@ -359,7 +381,7 @@ public partial class CharacterTemplate : CharacterBody2D //设置捡起物品的常规处理。 //You can supplement picking up state handling for more types of objects here. //您可以在这里补充更多类型对象的捡起状态处理。 - if (pickAbleItem is PickAbleTemplate pickAbleTemplate) + if (pickAbleItemNode2D is PickAbleTemplate pickAbleTemplate) { pickAbleTemplate.Owner = this; pickAbleTemplate.Picked = true; @@ -374,16 +396,16 @@ public partial class CharacterTemplate : CharacterBody2D { //If the selected item slot in the item container is a newly picked item, and there is no item in the hand, then we put the selected item into the hand. //如果物品容器内选中的物品槽是刚刚捡到的物品,且手里没有物品持有,那么我们将选中的物品放到手上。 - CurrentItem = pickAbleItem; + CurrentItem = pickAbleItemNode2D; } else { - pickAbleItem.Hide(); - pickAbleItem.ProcessMode = ProcessModeEnum.Disabled; + pickAbleItemNode2D.Hide(); + pickAbleItemNode2D.ProcessMode = ProcessModeEnum.Disabled; } - pickAbleItem.Reparent(ItemMarker2D); - pickAbleItem.Position = Vector2.Zero; + NodeUtils.CallDeferredReparent(ItemMarker2D, pickAbleItemNode2D); + pickAbleItemNode2D.Position = Vector2.Zero; return true; } diff --git a/scripts/character/Player.cs b/scripts/character/Player.cs index 7548cc4..380ee9e 100644 --- a/scripts/character/Player.cs +++ b/scripts/character/Player.cs @@ -17,8 +17,6 @@ namespace ColdMint.scripts.character; /// public partial class Player : CharacterTemplate { - private PackedScene? _floatLabelPackedScene; - private Control? _floatLabel; //Empty object projectile @@ -52,7 +50,17 @@ public partial class Player : CharacterTemplate CharacterName = TranslationServerUtils.Translate("default_player_name"); LogCat.LogWithFormat("player_spawn_debug", LogCat.LogLabel.Default, ReadOnlyCharacterName, GlobalPosition); - _floatLabelPackedScene = GD.Load("res://prefab/ui/FloatLabel.tscn"); + var floatLabelPackedScene = GD.Load("res://prefab/ui/FloatLabel.tscn"); + //Initializes the float label. + //初始化悬浮标签。 + _floatLabel = NodeUtils.InstantiatePackedScene(floatLabelPackedScene); + if (_floatLabel == null) + { + throw new NullReferenceException(TranslationServer.Translate("float_label_instantiate_failed")); + } + + _floatLabel.Hide(); + NodeUtils.CallDeferredAddChild(this, _floatLabel); _parabola = GetNode("Parabola"); _platformDetectionRayCast2D = GetNode("PlatformDetectionRayCast"); UpdateOperationTip(); @@ -147,9 +155,8 @@ public partial class Player : CharacterTemplate operationTipBuilder.Append(TranslationServerUtils.Translate("action_jump_down")); } - //If the PickingRangeBodiesList is not null and the length is greater than 0 - //如果PickingRangeBodiesList不是null,且长度大于0 - if (PickingRangeBodiesList is { Count: > 0 }) + var nearestItem = FindTheNearestItem(); + if (nearestItem != null) { operationTipBuilder.Append(' '); operationTipBuilder.Append("[color="); @@ -159,6 +166,11 @@ public partial class Player : CharacterTemplate TranslationServerUtils.Translate(InputMap.ActionGetEvents("pick_up")[0].AsText())); operationTipBuilder.Append("[/color]"); operationTipBuilder.Append(TranslationServerUtils.Translate("action_pick_up")); + if (nearestItem is IItem item) + { + operationTipBuilder.Append(item.Name); + } + operationTipLabel.Text = operationTipBuilder.ToString(); } @@ -232,11 +244,7 @@ public partial class Player : CharacterTemplate PickingRangeBodiesList?.Remove(pickAbleItem); } - if (_floatLabel != null) - { - _floatLabel.QueueFree(); - _floatLabel = null; - } + RecycleFloatLabel(); } } @@ -427,35 +435,41 @@ public partial class Player : CharacterTemplate return; } - if (_floatLabelPackedScene != null) + if (_floatLabel != null) { - //If there is a scene of floating text, then we generate floating text. - //如果有悬浮文本的场景,那么我们生成悬浮文本。 - _floatLabel?.QueueFree(); - _floatLabel = NodeUtils.InstantiatePackedScene(_floatLabelPackedScene); - if (_floatLabel != null) + if (node is not PickAbleTemplate pickAbleTemplate) { - NodeUtils.CallDeferredAddChild(node, _floatLabel); - var rotationDegreesNode2D = node2D.RotationDegrees; - var rotationDegreesNode2DAbs = Math.Abs(rotationDegreesNode2D); - _floatLabel.Position = rotationDegreesNode2DAbs > 90 - ? new Vector2(0, PromptTextDistance) - : new Vector2(0, -PromptTextDistance); - _floatLabel.RotationDegrees = 0 - rotationDegreesNode2D; - var label = _floatLabel.GetNode