using ColdMint.scripts.camp; using ColdMint.scripts.character; 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 == null || characterCamp == null) { 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 && Character.AttackObstacleDetection != 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; } }