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 inSightEnemies = new List(); private static Dictionary inSightDistanceList = new Dictionary(); 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 enemies = new List(); private static List inAttackEnemies = new List(); public static List 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 allFriends = new List(); private static List friendsInSight = new List(); public static List 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 patrolDistanceList = new Dictionary(); public static int FindNearestPointInPatrolInfo(GameUnit owner, List 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(); 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; } } } } }