using System.Collections.Generic; using UnityEngine; public static class TargetFinder { static SimpleHeap entitiesHeap = new SimpleHeap(); public static IList GetRandom(Bounds bounds, int maxCount) { var areaSize = BattleMgr.Instance.GetBgSize(); var result = new List(); for(int i = 0; i < maxCount; i++) { float rndX = Random.Range(bounds.min.x, bounds.max.x); float rndY = Random.Range(bounds.min.y, bounds.max.y); rndX = Mathf.Clamp(rndX, areaSize.bounds.min.x, areaSize.bounds.max.x); rndY = Mathf.Clamp(rndY, areaSize.bounds.min.y, areaSize.bounds.max.y); result.Add(new Vector2(rndX, rndY)); } return result; } public static List GetNears(Vector2 pivot, Bitset32.Mask filterTags, int maxCount = -1, ICollection except = null, bool ignoreExcepIfNoTarget = false) { entitiesHeap.Clear(); entitiesHeap.SetCompareFunc((a, b) => { float distA = (pivot - (Vector2)a.transform.position).sqrMagnitude; float distB = (pivot - (Vector2)b.transform.position).sqrMagnitude; return distA < distB; }); if(except is null) { BattleMgr.Instance.LoopAllBattleEntities((battleEntity) => { var entity = battleEntity as Entity; if (entity.HasTagsAny(filterTags)) { entitiesHeap.Push(entity); } return true; }); } else if (!ignoreExcepIfNoTarget) { BattleMgr.Instance.LoopAllBattleEntities((battleEntity) => { var entity = battleEntity as Entity; if (entity.HasTagsAny(filterTags) && !except.Contains(battleEntity)) { entitiesHeap.Push(entity); } return true; }); } else { var targetCandidates = new List(); BattleMgr.Instance.LoopAllBattleEntities((battleEntity) => { var entity = battleEntity as Entity; if(entity.HasTagsAny(filterTags)) { if(!except.Contains(battleEntity)) entitiesHeap.Push(entity); else targetCandidates.Add(entity); } return true; }); if (entitiesHeap.IsEmpty()) { for(int i = 0; i < targetCandidates.Count; i++) { entitiesHeap.Push(targetCandidates[i]); } } } var result = new List(); if(maxCount < 0) maxCount = entitiesHeap.Count; while (entitiesHeap.Count > 0 && result.Count < maxCount) { result.Add(entitiesHeap.Pop() as IBattleEntity); } return result; } public static bool TryFindNearest(Vector2 pivot, Bitset32.Mask filterTags, out IBattleEntity result, ICollection except = null, bool ignoreExcepIfNoTarget = false) { result = null; var nearests = GetNears(pivot, filterTags, 1, except, ignoreExcepIfNoTarget); if (nearests.Count > 0) result = nearests[0]; return result != null; } public static bool TryFindNearest(Vector2 pivot, Bounds bound, Bitset32.Mask filterTags, out IBattleEntity result, ICollection except = null, bool ignoreExcepIfNoTarget = false) { result = null; var nearests = GetNears(pivot, filterTags, -1, except, ignoreExcepIfNoTarget); for(int i = 0; i < nearests.Count; i++) { if (bound.Contains((nearests[i] as Entity).transform.position)) { result = nearests[i]; break; } } return result != null; } }