When the selected item slot A is selected, pressing the shortcut key of item slot A again will no longer invoke the press event of A.

当选中物品槽A时,再次按下物品槽A的快捷键,就不能再调用A的按下事件了。
This commit is contained in:
Cold-Mint 2024-06-06 21:05:51 +08:00
parent 21b3691925
commit 95515ddab2
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
10 changed files with 67 additions and 63 deletions

View File

@ -15,11 +15,6 @@ public partial class BehaviorNode : Node2D
InvokeBehaviorTreeNode(true, delta); InvokeBehaviorTreeNode(true, delta);
} }
// public override void _Process(double delta)
// {
// InvokeBehaviorTreeNode(false, delta);
// }
/// <summary> /// <summary>
/// <para>InvokeBehaviorTreeNode</para> /// <para>InvokeBehaviorTreeNode</para>
/// <para>调用行为树节点</para> /// <para>调用行为树节点</para>

View File

@ -1,5 +1,9 @@
namespace ColdMint.scripts.behaviorTree; namespace ColdMint.scripts.behaviorTree;
/// <summary>
/// <para>IBehavior Tree</para>
/// <para>行为树</para>
/// </summary>
public interface IBehaviorTree public interface IBehaviorTree
{ {
string? Id { get; } string? Id { get; }

View File

@ -3,6 +3,10 @@ using ColdMint.scripts.character;
namespace ColdMint.scripts.behaviorTree.ai; namespace ColdMint.scripts.behaviorTree.ai;
/// <summary>
/// <para>AI attack node</para>
/// <para>AI的攻击节点</para>
/// </summary>
public class AiAttackNode : BehaviorTreeNodeTemplate public class AiAttackNode : BehaviorTreeNodeTemplate
{ {
public AiCharacter? Character { get; set; } public AiCharacter? Character { get; set; }
@ -29,47 +33,49 @@ public class AiAttackNode : BehaviorTreeNodeTemplate
var selfCamp = CampManager.GetCamp(Character.CampId); var selfCamp = CampManager.GetCamp(Character.CampId);
foreach (var node in nodesInTheAttackRange) foreach (var node in nodesInTheAttackRange)
{ {
if (node is CharacterTemplate characterTemplate) if (node is not CharacterTemplate characterTemplate)
{ {
if (node == Character) continue;
{ }
continue;
} if (node == Character)
{
continue;
}
var characterCamp = CampManager.GetCamp(characterTemplate.CampId); var characterCamp = CampManager.GetCamp(characterTemplate.CampId);
var canCause = CampManager.CanCauseHarm(selfCamp, characterCamp); var canCause = CampManager.CanCauseHarm(selfCamp, characterCamp);
if (!canCause) if (!canCause)
{ {
continue; continue;
} }
if (selfCamp == null || characterCamp == null) if (selfCamp == null || characterCamp == null)
{ {
continue; continue;
} }
if (selfCamp.Id == characterCamp.Id)
{
//If it is the same side, do not attack, if allowed friend damage, this code will prevent the AI from actively attacking the player.
//如果是同一阵营不攻击如果允许友伤这段代码会阻止AI主动攻击玩家。
continue;
}
if (selfCamp.Id == characterCamp.Id) var distance = characterTemplate.GlobalPosition.DistanceTo(Character.GlobalPosition);
{ if (distance < closestDistance)
//如果是同一阵营,不攻击 {
continue; closestDistance = distance;
} closestEnemy = characterTemplate;
var distance = characterTemplate.GlobalPosition - Character.GlobalPosition;
var distanceLength = distance.Length();
if (distanceLength < closestDistance)
{
closestDistance = distanceLength;
closestEnemy = characterTemplate;
}
} }
} }
if (closestEnemy != null && Character.AttackObstacleDetection != null) if (closestEnemy != null && Character.AttackObstacleDetection != null)
{ {
//There are the closest enemies //With the nearest enemy and no obstacles
//有距离最近的敌人 //有距离最近的敌人,且没有障碍物
var distance = closestEnemy.GlobalPosition - Character.GlobalPosition; var distanceVector2 = closestEnemy.GlobalPosition - Character.GlobalPosition;
Character.AttackObstacleDetection.TargetPosition = distance; Character.AttackObstacleDetection.TargetPosition = distanceVector2;
if (Character.AttackObstacleDetection.GetCollider() == null) if (Character.AttackObstacleDetection.GetCollider() == null)
{ {
Character.StopMoving(); Character.StopMoving();

View File

@ -4,6 +4,7 @@ using ColdMint.scripts.character;
namespace ColdMint.scripts.behaviorTree.ai; namespace ColdMint.scripts.behaviorTree.ai;
/// <summary> /// <summary>
/// <para>AI patrol node</para>
/// <para>AI巡逻节点</para> /// <para>AI巡逻节点</para>
/// </summary> /// </summary>
public class AiPatrolNode : SelectorNode public class AiPatrolNode : SelectorNode

View File

@ -14,7 +14,7 @@ public class SequenceNode : BehaviorTreeNodeTemplate
/// <para>Check whether all child nodes are executed in sequence</para> /// <para>Check whether all child nodes are executed in sequence</para>
/// <para>所有子节点是否按顺序执行完毕</para> /// <para>所有子节点是否按顺序执行完毕</para>
/// </summary> /// </summary>
bool _complete = true; private bool _complete = true;
public override int Execute(bool isPhysicsProcess, double delta) public override int Execute(bool isPhysicsProcess, double delta)
{ {

View File

@ -8,12 +8,11 @@ namespace ColdMint.scripts.camp;
/// </summary> /// </summary>
public class Camp public class Camp
{ {
private readonly string _id;
private readonly List<string> _friendlyCampIdList; private readonly List<string> _friendlyCampIdList;
public Camp(string id) public Camp(string id)
{ {
_id = id; Id = id;
_friendlyCampIdList = new List<string>(); _friendlyCampIdList = new List<string>();
} }
@ -21,7 +20,7 @@ public class Camp
/// <para>Get camp ID</para> /// <para>Get camp ID</para>
/// <para>获取阵营ID</para> /// <para>获取阵营ID</para>
/// </summary> /// </summary>
public string Id => _id; public string Id { get; }
/// <summary> /// <summary>
/// <para>Get camp name</para> /// <para>Get camp name</para>

View File

@ -6,7 +6,7 @@ namespace ColdMint.scripts.camp;
/// <para>Camp manager</para> /// <para>Camp manager</para>
/// <para>阵营管理器</para> /// <para>阵营管理器</para>
/// </summary> /// </summary>
public class CampManager public static class CampManager
{ {
private static readonly Dictionary<string, Camp?> Camps = new Dictionary<string, Camp?>(); private static readonly Dictionary<string, Camp?> Camps = new Dictionary<string, Camp?>();

View File

@ -9,7 +9,7 @@ namespace ColdMint.scripts.character;
/// <para>The role played by computers</para> /// <para>The role played by computers</para>
/// <para>由电脑扮演的角色</para> /// <para>由电脑扮演的角色</para>
/// </summary> /// </summary>
public partial class AiCharacter : CharacterTemplate public sealed partial class AiCharacter : CharacterTemplate
{ {
/// <summary> /// <summary>
/// <para>How fast the character moves</para> /// <para>How fast the character moves</para>
@ -67,10 +67,11 @@ public partial class AiCharacter : CharacterTemplate
if (_attackArea != null) if (_attackArea != null)
{ {
//If true, the zone will detect objects or areas entering and leaving the zone.
//如果为true该区域将检测进出该区域的物体或区域。 //如果为true该区域将检测进出该区域的物体或区域。
_attackArea.Monitoring = true; _attackArea.Monitoring = true;
//Other regions cannot detect our pick region //Other areas can't detect our attack zone
//其他区域不能检测到我们的拾取区域 //其他区域不能检测到我们的攻击区域
_attackArea.Monitorable = false; _attackArea.Monitorable = false;
_attackArea.BodyEntered += EnterTheAttackArea; _attackArea.BodyEntered += EnterTheAttackArea;
_attackArea.BodyExited += ExitTheAttackArea; _attackArea.BodyExited += ExitTheAttackArea;
@ -83,12 +84,12 @@ public partial class AiCharacter : CharacterTemplate
// _behaviorNode.Root = patrolBehaviorTree.Root; // _behaviorNode.Root = patrolBehaviorTree.Root;
} }
protected virtual void EnterTheAttackArea(Node node) private void EnterTheAttackArea(Node node)
{ {
_nodesInTheAttackRange?.Add(node); _nodesInTheAttackRange?.Add(node);
} }
protected virtual void ExitTheAttackArea(Node node) private void ExitTheAttackArea(Node node)
{ {
_nodesInTheAttackRange?.Remove(node); _nodesInTheAttackRange?.Remove(node);
} }

View File

@ -6,7 +6,6 @@ using ColdMint.scripts.damage;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.health; using ColdMint.scripts.health;
using ColdMint.scripts.inventory; using ColdMint.scripts.inventory;
using ColdMint.scripts.map.events;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using ColdMint.scripts.weapon; using ColdMint.scripts.weapon;
using Godot; using Godot;
@ -259,16 +258,18 @@ public partial class CharacterTemplate : CharacterBody2D
/// </returns> /// </returns>
public bool PickItem(Node2D? pickAbleItem) public bool PickItem(Node2D? pickAbleItem)
{ {
if (pickAbleItem == null) //Empty reference checking is implicitly performed here.
//此处隐式的执行了空引用检查。
if (pickAbleItem is not IItem item)
{ {
return false; return false;
} }
if (_itemContainer == null) if (_itemContainer == null)
{ {
return false; return false;
} }
//Get the currently selected node //Get the currently selected node
//拿到当前选择的节点 //拿到当前选择的节点
var itemSlotNode = _itemContainer.GetSelectItemSlotNode(); var itemSlotNode = _itemContainer.GetSelectItemSlotNode();
@ -277,11 +278,6 @@ public partial class CharacterTemplate : CharacterBody2D
return false; return false;
} }
if (pickAbleItem is not IItem item)
{
return false;
}
//First check if we can pick up the item. //First check if we can pick up the item.
//先检查我们能否拾起此物品。 //先检查我们能否拾起此物品。
var canPick = _itemContainer.CanAddItem(item); var canPick = _itemContainer.CanAddItem(item);
@ -368,7 +364,7 @@ public partial class CharacterTemplate : CharacterBody2D
/// <para>Update the role's health bar</para> /// <para>Update the role's health bar</para>
/// <para>更新角色的健康条</para> /// <para>更新角色的健康条</para>
/// </summary> /// </summary>
private void UpDataHealthBar(DamageTemplate damageTemplate) private void UpDataHealthBar()
{ {
if (_healthBar == null) if (_healthBar == null)
{ {
@ -441,7 +437,7 @@ public partial class CharacterTemplate : CharacterBody2D
return true; return true;
} }
UpDataHealthBar(damageTemplate); UpDataHealthBar();
return true; return true;
} }

View File

@ -79,7 +79,7 @@ public partial class HotBar : HBoxContainer, IItemContainer
{ {
_selectIndex = count - 1; _selectIndex = count - 1;
} }
SelectItemSlot(oldSelectIndex, _selectIndex); SelectItemSlot(oldSelectIndex, _selectIndex);
} }
@ -223,6 +223,11 @@ public partial class HotBar : HBoxContainer, IItemContainer
/// </summary> /// </summary>
private void SelectItemSlot(int oldSelectIndex, int newSelectIndex) private void SelectItemSlot(int oldSelectIndex, int newSelectIndex)
{ {
if (oldSelectIndex == newSelectIndex)
{
return;
}
if (_itemSlotNodes == null) if (_itemSlotNodes == null)
{ {
return; return;
@ -286,10 +291,7 @@ public partial class HotBar : HBoxContainer, IItemContainer
{ {
return false; return false;
} }
else return itemSlotNode.SetItem(item);
{
return itemSlotNode.SetItem(item);
}
} }
public ItemSlotNode? GetSelectItemSlotNode() public ItemSlotNode? GetSelectItemSlotNode()