79 lines
2.5 KiB
C#
79 lines
2.5 KiB
C#
|
using ColdMint.scripts.camp;
|
|||
|
using ColdMint.scripts.character;
|
|||
|
using Godot;
|
|||
|
|
|||
|
namespace ColdMint.scripts.behaviorTree.ai;
|
|||
|
|
|||
|
public class AIAttackNode : BehaviorTreeNodeTemplate
|
|||
|
{
|
|||
|
public AICharacter Character { get; set; }
|
|||
|
|
|||
|
public override int Execute(bool isPhysicsProcess, double delta)
|
|||
|
{
|
|||
|
if (Character == null)
|
|||
|
{
|
|||
|
return Config.BehaviorTreeResult.Failure;
|
|||
|
}
|
|||
|
|
|||
|
var nodesInTheAttackRange = Character.NodesInTheAttackRange;
|
|||
|
if (nodesInTheAttackRange.Length == 0)
|
|||
|
{
|
|||
|
//No nodes are in range of the attack
|
|||
|
//没有节点在攻击范围内
|
|||
|
return Config.BehaviorTreeResult.Failure;
|
|||
|
}
|
|||
|
|
|||
|
//Save the nearest enemy
|
|||
|
//保存最近的敌人
|
|||
|
CharacterTemplate closestEnemy = null;
|
|||
|
var closestDistance = float.MaxValue;
|
|||
|
var selfCamp = CampManager.GetCamp(Character.CampId);
|
|||
|
foreach (var node in nodesInTheAttackRange)
|
|||
|
{
|
|||
|
if (node is CharacterTemplate characterTemplate)
|
|||
|
{
|
|||
|
if (node == Character)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
var characterCamp = CampManager.GetCamp(characterTemplate.CampId);
|
|||
|
var canCause = CampManager.CanCauseHarm(selfCamp, characterCamp);
|
|||
|
if (!canCause)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (selfCamp.ID == characterCamp.ID)
|
|||
|
{
|
|||
|
//如果是同一阵营,不攻击
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
var distance = characterTemplate.GlobalPosition - Character.GlobalPosition;
|
|||
|
var distanceLength = distance.Length();
|
|||
|
if (distanceLength < closestDistance)
|
|||
|
{
|
|||
|
closestDistance = distanceLength;
|
|||
|
closestEnemy = characterTemplate;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (closestEnemy != null)
|
|||
|
{
|
|||
|
//There are the closest enemies
|
|||
|
//有距离最近的敌人
|
|||
|
var distance = closestEnemy.GlobalPosition - Character.GlobalPosition;
|
|||
|
Character.AttackObstacleDetection.TargetPosition = distance;
|
|||
|
if (Character.AttackObstacleDetection.GetCollider() == null)
|
|||
|
{
|
|||
|
Character.StopMoving();
|
|||
|
Character.AimTheCurrentItemAtAPoint(closestEnemy.GlobalPosition);
|
|||
|
Character.UseItem(closestEnemy.GlobalPosition);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return Config.BehaviorTreeResult.Success;
|
|||
|
}
|
|||
|
}
|