using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace rabi_splitter_WPF { public static partial class BossFightIdentifier { private static ILookup, BossFight> _matchMusicAndMap; private static ILookup _matchMusic; private static ILookup _matchMap; private static BossFight[] _remainingDescriptions; static BossFightIdentifier() { // Build dictionaries here. var specifiedMusicAndMap = new List(); var specifiedMusicOnly = new List(); var specifiedMapOnly = new List(); var specifiedNeither = new List(); foreach (var bossFight in BossFight.GetBossFights()) { //if (bossFight == null) continue; if (bossFight.music != null) { if (bossFight.map != null) specifiedMusicAndMap.Add(bossFight); else specifiedMusicOnly.Add(bossFight); } else { if (bossFight.map != null) specifiedMapOnly.Add(bossFight); else specifiedNeither.Add(bossFight); } } _matchMusicAndMap = specifiedMusicAndMap.ToLookup(bossFight => new Tuple(bossFight.music.Value, bossFight.map.Value), bossFight => bossFight); _matchMusic = specifiedMusicOnly.ToLookup(bossFight => bossFight.music.Value, bossFight => bossFight); _matchMap = specifiedMapOnly.ToLookup(bossFight => bossFight.map.Value, bossFight => bossFight); _remainingDescriptions = specifiedNeither.ToArray(); } private static bool Matches(BossFight bossFight, HashSet startingBosses, Music music, Map map) { if (bossFight.startingBosses != null && !bossFight.startingBosses.SetEquals(startingBosses)) return false; if (bossFight.extraCondition == null) return true; return bossFight.extraCondition(startingBosses, music, map); } public static BossFight IdentifyBossFight(MemorySnapshot snapshot) { Music? music_ = StaticData.GetMusic(snapshot.musicid); Map? map_ = StaticData.GetMap(snapshot.mapid); if (music_ == null || map_ == null) return BossFight.UNKNOWN; var music = music_.Value; var map = map_.Value; var startingBosses = new HashSet(snapshot.bossList .Select(bossStats => StaticData.GetBoss(bossStats.id)) .Where(boss => boss != null) .Select(boss => boss.Value) ); foreach (var bossFight in _matchMusicAndMap[new Tuple(music, map)]) { if (Matches(bossFight, startingBosses, music, map)) return bossFight; } foreach (var bossFight in _matchMusic[music]) { if (Matches(bossFight, startingBosses, music, map)) return bossFight; } foreach (var bossFight in _matchMap[map]) { if (Matches(bossFight, startingBosses, music, map)) return bossFight; } return _remainingDescriptions.FirstOrDefault(bossFight => Matches(bossFight, startingBosses, music, map)) ?? BossFight.UNKNOWN; } } }