using System; using System.Collections.Generic; namespace PKHeX.Core.Searching { /// /// searching utility /// public static class SearchUtil { // Future: Might need to clamp down further for generations that cannot exist in the current format. public static bool SatisfiesFilterFormat(PKM pk, int format, SearchComparison formatOperand) => formatOperand switch { SearchComparison.GreaterThanEquals when pk.Format < format => false, SearchComparison.Equals when pk.Format != format => false, SearchComparison.LessThanEquals when pk.Format > format => false, _ when format <= 2 => pk.Format <= 2, // 1-2 _ when format <= 6 => pk.Format >= 3, // 3-6 _ => true, }; public static bool SatisfiesFilterGeneration(PKM pk, int generation) => generation switch { 1 => pk.VC || pk.Format < 3, 2 => pk.VC || pk.Format < 3, _ => pk.Generation == generation, }; public static bool SatisfiesFilterLevel(PKM pk, SearchComparison option, int level) { if (level > 100) return true; // why??? return option switch { SearchComparison.LessThanEquals => pk.Stat_Level <= level, SearchComparison.Equals => pk.Stat_Level == level, SearchComparison.GreaterThanEquals => pk.Stat_Level >= level, _ => true, }; } public static bool SatisfiesFilterEVs(PKM pk, int option) => option switch { 1 => pk.EVTotal == 0, // None (0) 2 => pk.EVTotal is (not 0) and < 128, // Some (127-1) 3 => pk.EVTotal is >= 128 and < 508, // Half (128-507) 4 => pk.EVTotal >= 508, // Full (508+) _ => true, }; public static bool SatisfiesFilterIVs(PKM pk, int option) => option switch { 1 => pk.IVTotal <= 90, // <= 90 2 => pk.IVTotal is > 90 and <= 120, // 91-120 3 => pk.IVTotal is > 120 and <= 150, // 121-150 4 => pk.IVTotal is > 150 and < 180, // 151-179 5 => pk.IVTotal >= 180, // 180+ 6 => pk.IVTotal == 186, // == 186 _ => true, }; public static bool SatisfiesFilterMoves(PKM pk, IEnumerable requiredMoves) { foreach (var m in requiredMoves) { if (!pk.HasMove(m)) return false; } return true; } public static bool SatisfiesFilterBatchInstruction(PKM pk, IReadOnlyList filters) { return BatchEditing.IsFilterMatch(filters, pk); // Compare across all filters } public static Func GetCloneDetectMethod(CloneDetectionMethod method) => method switch { CloneDetectionMethod.HashPID => HashByPID, _ => HashByDetails, }; public static string HashByDetails(PKM pk) => pk.Format switch { 1 => $"{pk.Species:000}{((PK1) pk).DV16:X4}", 2 => $"{pk.Species:000}{((PK2) pk).DV16:X4}", _ => $"{pk.Species:000}{pk.PID:X8}{string.Join(" ", pk.IVs)}{pk.Form:00}", }; public static string HashByPID(PKM pk) => pk.Format switch { 1 => $"{((PK1) pk).DV16:X4}", 2 => $"{((PK2) pk).DV16:X4}", _ => $"{pk.PID:X8}", }; public static IEnumerable GetClones(IEnumerable res, CloneDetectionMethod type = CloneDetectionMethod.HashDetails) { var method = GetCloneDetectMethod(type); return GetExtraClones(res, method); } public static IEnumerable GetUniques(IEnumerable db, Func method) { var hs = new HashSet(); foreach (var t in db) { var hash = method(t); if (hs.Contains(hash)) continue; yield return t; hs.Add(hash); } } public static IEnumerable GetExtraClones(IEnumerable db, Func method) { var hs = new HashSet(); foreach (var t in db) { var hash = method(t); if (hs.Contains(hash)) yield return t; else hs.Add(hash); } } } }