2024-04-28 13:55:19 +00:00
|
|
|
|
using ColdMint.scripts.camp;
|
|
|
|
|
using ColdMint.scripts.character;
|
|
|
|
|
|
|
|
|
|
namespace ColdMint.scripts.behaviorTree.ai;
|
|
|
|
|
|
2024-05-08 10:22:04 +00:00
|
|
|
|
public class AiAttackNode : BehaviorTreeNodeTemplate
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
2024-05-08 10:22:04 +00:00
|
|
|
|
public AiCharacter? Character { get; set; }
|
2024-04-28 13:55:19 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
//保存最近的敌人
|
2024-05-08 10:22:04 +00:00
|
|
|
|
CharacterTemplate? closestEnemy = null;
|
2024-04-28 13:55:19 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 10:22:04 +00:00
|
|
|
|
if (selfCamp == null || characterCamp == null)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (selfCamp.Id == characterCamp.Id)
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
|
|
|
|
//如果是同一阵营,不攻击
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var distance = characterTemplate.GlobalPosition - Character.GlobalPosition;
|
|
|
|
|
var distanceLength = distance.Length();
|
|
|
|
|
if (distanceLength < closestDistance)
|
|
|
|
|
{
|
|
|
|
|
closestDistance = distanceLength;
|
|
|
|
|
closestEnemy = characterTemplate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 10:22:04 +00:00
|
|
|
|
if (closestEnemy != null && Character.AttackObstacleDetection != null)
|
2024-04-28 13:55:19 +00:00
|
|
|
|
{
|
|
|
|
|
//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;
|
|
|
|
|
}
|
|
|
|
|
}
|