using System.Collections.Generic; using UnityEngine; namespace ProjectI.Enemies { public sealed class EnemyTargetSelection { public EnemyTargetKey? Selected { get; private set; } #if UNITY_EDITOR || DEVELOPMENT_BUILD public string Reason { get; private set; } = "No eligible evidence"; #endif public double HoldUntil { get; private set; } private readonly double holdSeconds; public EnemyTargetSelection(double holdSeconds = 1.5) { this.holdSeconds = holdSeconds; } public void Clear(string reason = null) { Selected = null; HoldUntil = 0; #if UNITY_EDITOR || DEVELOPMENT_BUILD Reason = reason ?? "No eligible evidence"; #endif } public bool Select(IReadOnlyList memories, Vector3 origin, double now, out EnemyTargetKey target) { target = default; EnemyObservationRules best = null, incumbent = null; int bestQuality = -1, incumbentQuality = -1; float bestDistance = float.PositiveInfinity; foreach (var memory in memories) { if (!memory.TryBest(now, out var evidence, out int quality)) continue; float distance = (evidence.Position - origin).sqrMagnitude; if (Selected.HasValue && Selected.Value.Equals(memory.Key)) { incumbent = memory; incumbentQuality = quality; } if (quality > bestQuality || quality == bestQuality && (distance < bestDistance || distance == bestDistance && (best == null || memory.Key.NetworkObjectId < best.Key.NetworkObjectId))) { best = memory; bestQuality = quality; bestDistance = distance; } } if (best == null) { Clear(); return false; } if (incumbent != null && now < HoldUntil && incumbentQuality == bestQuality) { target = incumbent.Key; #if UNITY_EDITOR || DEVELOPMENT_BUILD Reason = "Holding equal-quality preference"; #endif return true; } target = best.Key; if (!Selected.HasValue || !Selected.Value.Equals(target)) { #if UNITY_EDITOR || DEVELOPMENT_BUILD Reason = incumbent != null && bestQuality > incumbentQuality ? "Better evidence" : "Best evidence, nearest known position"; #endif Selected = target; HoldUntil = now + holdSeconds; } #if UNITY_EDITOR || DEVELOPMENT_BUILD else Reason = "Best evidence, nearest known position"; #endif return true; } } }