using System;
using Framework;
using System.Linq;
using Gameplay.Unit;
using Gameplay.Area;
using Gameplay.Level;
using cfg.CharacterCfg;
using Gameplay.Character;
using System.Collections.Generic;
namespace Gameplay.AI
{
public static partial class AIUtils
{
#region 寻找敌人
///
/// 寻找视野内的最近敌人 range为-1则为索敌范围
///
public static GameUnit FindNearestTarget(GameUnit owner, int range = -1, Ejob job = Ejob.Job_Other)
{
try
{
var inSightDistanceDic = FindEnemiesInRange(owner, range, job);
return GetNearestUnit(inSightDistanceDic);
}
catch (Exception e)
{
DebugUtil.LogError("AIUtils.FindNearestTarget error: {0}", e);
return null;
}
}
///
/// 寻找范围内符合条件的所有敌人
///
public static Dictionary FindEnemiesInRange(GameUnit owner, int range = -1,
Ejob job = Ejob.Job_Other, uint targetID = 0)
{
if (owner == null || range == 0) return null;
var enemies = GameUnitManager.instance.SearchEnemies(owner);
var filter = new EnemyFilter(owner, range, job, targetID);
return AITargetFinder.FindUnits(owner, enemies, filter);
}
///
/// 获取最近的单位
///
public static GameUnit GetNearestUnit(Dictionary units)
{
var minDistance = float.MaxValue;
GameUnit nearestUnit = null;
foreach (var pair in units)
{
if (minDistance > pair.Value)
{
minDistance = pair.Value;
nearestUnit = pair.Key;
}
}
return nearestUnit;
}
///
/// 获取更近的攻击来源单位
///
public static GameUnit GetNearestAttackGameUnit(GameUnit owner, GameUnit newUnit, GameUnit unit)
{
try
{
if (owner == null || newUnit == null || unit == null) return null;
var map = LevelManager.Instance.CurrentLevel.Map;
if (map == null) return null;
var ownerCellIndex = owner.transData?.cellIndex;
var unitCellIndex = unit.transData?.cellIndex;
var newUnitCellIndex = newUnit.transData?.cellIndex;
if (!ownerCellIndex.HasValue || !unitCellIndex.HasValue || !newUnitCellIndex.HasValue) return null;
var distance = MapUtils.Distance(map, ownerCellIndex.Value, unitCellIndex.Value);
var newDistance = MapUtils.Distance(map, ownerCellIndex.Value, newUnitCellIndex.Value);
return distance <= newDistance ? unit : newUnit;
}
catch (Exception e)
{
DebugUtil.LogError("AIUtils.GetNearestGameUnit error: {0}", e);
// 异常返回默认单位
return unit;
}
}
#endregion
#region 寻找友军
///
/// 通过MonsterID寻找友军 只返回第一个Monster
///
public static GameUnit FindFriendByMonsterID(int id)
{
foreach (var unit in GameUnitManager.instance.totalUnits.unitList)
{
if (unit.unitLevelData != null && !unit.statusData.isDead && unit.unitLevelData.monsterId == id)
{
return unit;
}
}
return null;
}
///
/// 寻找视野内的最近敌人 range为-1则为索敌范围
///
public static GameUnit FindNearestFriend(GameUnit owner, int range = -1, Ejob job = Ejob.Job_Other)
{
try
{
var inSightDistanceDic = FindFriendInRange(owner, range, job);
return GetNearestUnit(inSightDistanceDic);
}
catch (Exception e)
{
DebugUtil.LogError("AIUtils.FindNearestFriend error: {0}", e);
return null;
}
}
///
/// 寻找范围内符合条件的友军
///
public static Dictionary FindFriendInRange(GameUnit owner, int range = -1,
Ejob job = Ejob.Job_Other)
{
if (owner == null || range == 0) return null;
var friends = GameUnitManager.instance.SearchFriends(owner);
var filter = new FriendFilter(owner, range, job);
return AITargetFinder.FindUnits(owner, friends, filter);
}
///
/// 检测某个地格是否有友军单位
///
public static GameUnit FindFriendByCellIndex(int cellIndex)
{
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
foreach (var unit in units)
{
if (unit.commonData.troopId == ETroopsId.Enemy)
{
return unit;
}
}
return null;
}
#endregion
#region 寻找随机目标
public static int FindRandomCell(GameUnit owner, int maxStep = 0)
{
try
{
var map = LevelManager.Instance.CurrentLevel?.Map;
if (map == null || owner == null) return -1;
var cellIndex = owner.transData.cellIndex;
if (!AreaManager.instance.CheckContainsMoveUnit(cellIndex))
return -1;
var randomCells = new List();
for (var i = 1; i <= maxStep; i++)
{
var minSteps = i - 1;
var maxSteps = i;
var cells = map.TerrainGridSystem.CellGetNeighboursWithinRange(cellIndex, minSteps, maxSteps,
canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
foreach (var cell in cells)
{
if (!CheckCellCanSelect(cell)) continue;
if (!PathFinder.CanBasePass(cell, owner)) continue;
if (AreaManager.instance.CheckContainsMoveUnit(cell)) continue;
if (maxSteps > 1)
{
if (CheckPathExits(owner, cell))
{
randomCells.Add(cell);
}
}
else
{
randomCells.Add(cell);
}
}
}
if (randomCells.Count == 0)
return -1;
var randomIndex = UnityEngine.Random.Range(0, randomCells.Count);
return randomCells[randomIndex];
}
catch (Exception e)
{
DebugUtil.LogError("AIUtils.FindRandomCell error: {0}", e);
return -1;
}
}
///
/// 寻找随机单位
///
public static GameUnit FindRandomTarget(GameUnit owner, uint enemy, int range = -1)
{
try
{
var targetID = enemy;
var inSightDistanceDic = FindEnemiesInRange(owner, range, targetID: targetID);
return GetRandomUnit(inSightDistanceDic);
}
catch (Exception e)
{
DebugUtil.LogError("AIUtils.FindRandomTarget error: {0}", e);
return null;
}
}
///
/// 获取随机单位
///
private static GameUnit GetRandomUnit(Dictionary units)
{
if (units == null || units.Count == 0)
return null;
var unitList = units.Keys.ToList();
var randomUnit = unitList[UnityEngine.Random.Range(0, unitList.Count)];
return randomUnit;
}
#endregion
#region 组内单位 寻找 判断
public static bool GroupTargetInRange(GameUnit owner, List group)
{
var inRange = false;
var groupFriends = FindGroupUnits(owner, group);
foreach (var groupFriend in groupFriends)
{
var targetID = groupFriend.unitLevelData.AIBattleInfo.Value.targetID;
if (targetID == Constants.INVALID_UINT_ID) continue;
var target = GameUnitManager.instance.infightUnits.Search(targetID);
var distance = GetDistance(owner.transData.cellIndex, target.transData.cellIndex);
if (distance <= groupFriend.fightData.trackRange)
{
inRange = true;
break;
}
}
return inRange;
}
public static List FindGroupUnits(GameUnit owner, List group)
{
var groupUnits = new List();
if (owner == null || group == null || group.Count == 0)
return groupUnits;
var friends = GameUnitManager.instance.SearchFriends(owner);
foreach (var friend in friends)
{
if (friend.unitLevelData == null || friend.unitLevelData.AIBattleInfo == null) continue;
var unitGroups = friend.unitLevelData.AIBattleInfo.Value.groupInfo;
if (unitGroups == null || unitGroups.Count <= 0) continue;
// 检查当前单位的组ID列表与传入的组ID列表是否有交集
foreach (var groupId in unitGroups)
{
if (group.Contains(groupId))
{
groupUnits.Add(friend);
break; // 找到一个匹配就可以添加该单位,无需继续检查其他组ID
}
}
}
return groupUnits;
}
#endregion
}
}