NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/AI/AIUtils.cs

243 lines
8.4 KiB
C#

using Framework;
using Gameplay.Unit;
using Gameplay.Level;
using System.Collections.Generic;
using static Gameplay.Level.LevelData;
namespace Gameplay.AI
{
public static class AIUtils
{
private static List<GameUnit> inSightEnemies = new List<GameUnit>();
private static Dictionary<GameUnit, int> inSightDistanceList = new Dictionary<GameUnit, int>();
public static GameUnit FindNearestEnemyInSightDistance(GameUnit owner)
{
if (owner == null) return null;
var map = LevelManager.Instance.CurrentLevel.Map;
if (map == null) return null;
inSightEnemies.Clear();
inSightDistanceList.Clear();
GameUnitManager.instance.characterManager.SearchEnemies(owner, inSightEnemies);
var ownerCellIndex = owner.transData?.cellIndex;
for (var i = 0; i < inSightEnemies.Count; i++)
{
var enemy = inSightEnemies[i];
if (enemy == null)
{
continue;
}
var enemyCellIndex = enemy.transData?.cellIndex;
if (!ownerCellIndex.HasValue || !enemyCellIndex.HasValue)
{
continue;
}
var distance = MapUtils.Distance(map, ownerCellIndex.Value, enemyCellIndex.Value);
if (distance <= owner.fightData.findEnemyRange)
{
inSightDistanceList.Add(enemy, distance);
}
}
if (inSightDistanceList.Count <= 0)
{
return null;
}
else
{
var minDistance = float.MaxValue;
GameUnit nearestEnemy = null;
foreach (var pair in inSightDistanceList)
{
if (minDistance > pair.Value)
{
minDistance = pair.Value;
nearestEnemy = pair.Key;
}
}
return nearestEnemy;
}
}
private static List<GameUnit> enemies = new List<GameUnit>();
private static List<GameUnit> inAttackEnemies = new List<GameUnit>();
public static List<GameUnit> FindEnemiesInAttackDistance(GameUnit owner)
{
if (owner == null) return null;
var map = LevelManager.Instance.CurrentLevel.Map;
if (map == null) return null;
enemies.Clear();
inAttackEnemies.Clear();
GameUnitManager.instance.characterManager.SearchEnemies(owner, enemies);
var ownerCellIndex = owner.transData?.cellIndex;
for (int i = 0; i < enemies.Count; i++)
{
var enemy = enemies[i];
if (enemy == null || enemy.GetID() == owner.GetID())
{
continue;
}
var enemyCellIndex = enemy.transData?.cellIndex;
if (!ownerCellIndex.HasValue || !enemyCellIndex.HasValue)
{
continue;
}
var distance = MapUtils.Distance(map, ownerCellIndex.Value, enemyCellIndex.Value);
if (distance <= owner.fightData.attackDistance)
{
inAttackEnemies.Add(enemy);
}
}
return inAttackEnemies;
}
private static List<GameUnit> allFriends = new List<GameUnit>();
private static List<GameUnit> friendsInSight = new List<GameUnit>();
public static List<GameUnit> FindFriendsInSightDistance(GameUnit owner)
{
if (owner == null) return null;
var map = LevelManager.Instance.CurrentLevel.Map;
if (map == null) return null;
allFriends.Clear();
friendsInSight.Clear();
GameUnitManager.instance.characterManager.SearchFriends(owner, allFriends);
var ownerCellIndex = owner.transData?.cellIndex;
for (var i = 0; i < allFriends.Count; i++)
{
var friend = allFriends[i];
if (friend == null || friend.GetID() == owner.GetID())
{
continue;
}
var friendCellIndex = friend.transData?.cellIndex;
if (!ownerCellIndex.HasValue || !friendCellIndex.HasValue)
{
continue;
}
var distance = MapUtils.Distance(map, ownerCellIndex.Value, friendCellIndex.Value);
if (distance <= owner.fightData.findEnemyRange)
{
friendsInSight.Add(friend);
}
}
return friendsInSight;
}
public static GameUnit GetNearestGameUnit(GameUnit owner, GameUnit newUnit, GameUnit unit)
{
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;
}
private static Dictionary<int, int> patrolDistanceList = new Dictionary<int, int>();
public static int FindNearestPointInPatrolInfo(GameUnit owner, List<PatrolInfo> patrolInfos)
{
if (owner == null) return Constants.INVALID_ID;
var map = LevelManager.Instance.CurrentLevel.Map;
if (map == null) return Constants.INVALID_ID;
patrolDistanceList.Clear();
var ownerCellIndex = owner.transData?.cellIndex;
for (var i = 0; i < patrolInfos.Count; i++)
{
var point = map.BlockPosition2TGSCellIndex(patrolInfos[i].patrolPoint);
if (!ownerCellIndex.HasValue || point == Constants.INVALID_ID)
{
continue;
}
patrolDistanceList.Add(i,
MapUtils.Distance(map, ownerCellIndex.Value, point));
}
var minDistance = int.MaxValue;
int nearestPoint = 0;
foreach (var pair in patrolDistanceList)
{
if (minDistance > pair.Value)
{
minDistance = pair.Value;
nearestPoint = pair.Key;
}
}
return nearestPoint;
}
public static bool IsNeedStop(GameUnit owner)
{
return owner.statusData.isOnVehicle || owner.statusData.isChaos || owner.statusData.isStun
|| owner.statusData.isLockPos || owner.statusData.isRetreat;
}
public static void ActiveAIAttack(GameUnit owner)
{
if (owner == null) return;
if (owner.statusData.isAttackActive) return;
var map = LevelManager.Instance.CurrentLevel.Map;
if (map == null) return;
var tempInSightEnemies = new List<GameUnit>();
GameUnitManager.instance.characterManager.SearchEnemies(owner, tempInSightEnemies);
if(tempInSightEnemies.Count<=0) return;
var ownerCellIndex = owner.transData?.cellIndex;
for (var i = 0; i < inSightEnemies.Count; i++)
{
var enemy = inSightEnemies[i];
if (enemy == null)
{
continue;
}
var enemyCellIndex = enemy.transData?.cellIndex;
if (!ownerCellIndex.HasValue || !enemyCellIndex.HasValue)
{
continue;
}
var distance = MapUtils.Distance(map, ownerCellIndex.Value, enemyCellIndex.Value);
if (distance <= owner.fightData.findEnemyRange)
{
owner.statusData.isAttackActive = true;
return;
}
}
}
}
}