| | | 1 | | using static Chronicis.Client.Services.RenderDefinitionHelpers; |
| | | 2 | | |
| | | 3 | | namespace Chronicis.Client.Services; |
| | | 4 | | |
| | | 5 | | /// <summary> |
| | | 6 | | /// Detects prefix-based field groups and identifies ability score groups. |
| | | 7 | | /// </summary> |
| | | 8 | | public static class PrefixGroupDetector |
| | | 9 | | { |
| | | 10 | | public static List<PrefixGroup> DetectGroups(List<FieldInfo> fields) |
| | | 11 | | { |
| | 21 | 12 | | var candidates = new Dictionary<string, List<FieldInfo>>(StringComparer.OrdinalIgnoreCase); |
| | | 13 | | |
| | 178 | 14 | | foreach (var fi in fields) |
| | | 15 | | { |
| | 68 | 16 | | var lastUnderscore = fi.Name.LastIndexOf('_'); |
| | 68 | 17 | | if (lastUnderscore <= 0) |
| | | 18 | | continue; |
| | | 19 | | |
| | 56 | 20 | | var prefix = fi.Name[..lastUnderscore]; |
| | 56 | 21 | | if (!candidates.ContainsKey(prefix)) |
| | 18 | 22 | | candidates[prefix] = new List<FieldInfo>(); |
| | 56 | 23 | | candidates[prefix].Add(fi); |
| | | 24 | | } |
| | | 25 | | |
| | 21 | 26 | | var validPrefixes = candidates |
| | 21 | 27 | | .Where(kv => kv.Value.Count >= 3) |
| | 21 | 28 | | .ToList(); |
| | 21 | 29 | | validPrefixes.Sort((a, b) => b.Key.Length.CompareTo(a.Key.Length)); |
| | | 30 | | |
| | 21 | 31 | | var claimed = new HashSet<string>(StringComparer.OrdinalIgnoreCase); |
| | 21 | 32 | | var groups = new List<PrefixGroup>(); |
| | | 33 | | |
| | 70 | 34 | | foreach (var kv in validPrefixes) |
| | | 35 | | { |
| | 14 | 36 | | var unclaimed = kv.Value.Where(f => !claimed.Contains(f.Name)).ToList(); |
| | 14 | 37 | | groups.Add(new PrefixGroup |
| | 14 | 38 | | { |
| | 14 | 39 | | Prefix = kv.Key, |
| | 14 | 40 | | Label = FormatGroupLabel(kv.Key), |
| | 14 | 41 | | Fields = unclaimed |
| | 14 | 42 | | }); |
| | 130 | 43 | | foreach (var f in unclaimed) |
| | 51 | 44 | | claimed.Add(f.Name); |
| | | 45 | | } |
| | | 46 | | |
| | 21 | 47 | | return groups; |
| | | 48 | | } |
| | | 49 | | |
| | | 50 | | public static bool IsAbilityScoreGroup(PrefixGroup group) |
| | | 51 | | { |
| | 13 | 52 | | if (group.Fields.Count != 6) |
| | 9 | 53 | | return false; |
| | 4 | 54 | | var suffixes = group.Fields |
| | 4 | 55 | | .Select(f => StripPrefix(f.Name, group.Prefix).ToLowerInvariant()) |
| | 4 | 56 | | .ToHashSet(); |
| | 4 | 57 | | return AbilitySuffixes.All(s => suffixes.Contains(s)); |
| | | 58 | | } |
| | | 59 | | } |
| | | 60 | | |
| | | 61 | | /// <summary> |
| | | 62 | | /// A group of fields sharing a common prefix. |
| | | 63 | | /// </summary> |
| | | 64 | | public class PrefixGroup |
| | | 65 | | { |
| | | 66 | | public string Prefix { get; set; } = ""; |
| | | 67 | | public string Label { get; set; } = ""; |
| | | 68 | | public List<FieldInfo> Fields { get; set; } = new(); |
| | | 69 | | } |